Complete reference for all Calendar MCP tools. Connect via the Model Context Protocol.
1. Connect a Google Calendar at calendarmcp.ai (OAuth, or service-account sharing if your account has Google Advanced Protection).
2. (Optional) Add more Google accounts from the dashboard — one API key multiplexes all of them.
3. Grab your API key from the dashboard. Use the Read/Write matrix to narrow what the key can touch.
4. Connect your MCP client:
Endpoint
https://calendarmcp.ai/api/mcpAuth Header
Authorization: Bearer YOUR_API_KEYA single CalendarMCP API key can hold multiple Google accounts — any mix of OAuth-connected accounts and service-account-shared calendars — and each calendar has its own Read / Write grant for the key.
Sign in with Google. Full read and write, including attendee invites.
Share a calendar with CalendarMCP’s service account email. No Google sign-in needed.
Per-calendar permissions are enforced by the server, not just the client:
PermissionError with a clear message.Use list_calendars at runtime to discover exactly what the key can do, including canRead / canWrite / connectionKind per calendar.
Timed events: Use startDateTime / endDateTime with ISO 8601 timestamps.
All-day events: Use startDate / endDate with YYYY-MM-DD strings. End date is exclusive (a Jan 15-16 event needs endDate of 2024-01-17).
Rule: Never mix date and dateTime fields on the same event.
query param) may not work on non-primary calendars (Google API limitation).batch_update_events max 50 events per call. For larger batches, make multiple calls.list_eventsList events from one or more Google Calendars within a time range. Auto-paginates up to 2500 results. When no calendarId is provided, queries every enabled calendar the API key can read — across every connected Google account — in parallel (one request per connection) and merges results sorted by start time.
calendarIdstringoptionalCalendar ID. Omit to fan out across every enabled calendar this API key can read.timeMinstringoptionalStart of time range (ISO 8601, e.g. 2026-01-01T00:00:00Z)timeMaxstringoptionalEnd of time range (ISO 8601)maxResultsnumberoptionalMax events to return (1-2500, default: 10). Auto-paginates internally.querystringoptionalFree text search. Note: may not work on non-primary calendars (Google API limitation).singleEventsbooleanoptionalExpand recurring events into instances (default: true)orderBystringoptional"startTime" or "updated" (default: startTime)pageTokenstringoptionalPagination token from a previous response.{
"tool": "list_events",
"arguments": {
"timeMin": "2026-04-01T00:00:00Z",
"timeMax": "2026-04-30T23:59:59Z",
"maxResults": 50
}
}Array of event objects with id, summary, description, location, start, end, status, attendees, reminders, transparency, visibility, colorId, recurrence, htmlLink, organizer.
get_eventGet full details of a specific calendar event by its ID. Returns all fields including reminders, transparency, visibility, and colorId.
calendarIdstringoptionalCalendar ID. Omit for default.eventIdstringrequiredThe event ID to retrieve.{
"tool": "get_event",
"arguments": {
"eventId": "abc123def456"
}
}Single event object with all fields.
create_eventCreate a new calendar event with attendees, location, reminders, recurrence, transparency, visibility, and color. Requires write permission on the target calendar. Events created on service-account-connected calendars cannot include attendees — Google does not allow service accounts to dispatch invites on personal calendars. Connect the same Google account via OAuth if you need to invite attendees.
calendarIdstringoptionalCalendar ID. Omit for default.summarystringrequiredEvent title.descriptionstringoptionalEvent description.locationstringoptionalEvent location.startDateTimestringoptionalStart date/time in ISO 8601 (e.g. 2026-01-15T10:00:00-07:00). For timed events.endDateTimestringoptionalEnd date/time in ISO 8601. For timed events.startDatestringoptionalStart date for all-day events (YYYY-MM-DD). Use instead of startDateTime.endDatestringoptionalEnd date for all-day events (YYYY-MM-DD, exclusive). Use instead of endDateTime.timeZonestringoptionalTime zone (e.g. America/Denver).attendeesstring[]optionalList of attendee email addresses.remindersobjectoptional{ useDefault: boolean, overrides?: [{ method: "email"|"popup", minutes: number }] }recurrencestring[]optionalRRULE format, e.g. ["RRULE:FREQ=WEEKLY;COUNT=10"]transparencystringoptional"opaque" (busy, default) or "transparent" (free).visibilitystringoptional"default", "public", "private", or "confidential".colorIdstringoptionalColor ID (1-11).{
"tool": "create_event",
"arguments": {
"summary": "Team Standup",
"startDateTime": "2026-04-20T09:00:00-07:00",
"endDateTime": "2026-04-20T09:30:00-07:00",
"timeZone": "America/Denver",
"attendees": [
"alice@example.com",
"bob@example.com"
],
"reminders": {
"useDefault": false,
"overrides": [
{
"method": "popup",
"minutes": 10
}
]
}
}
}Created event object.
update_eventUpdate an existing calendar event. Partial update via PATCH — only provide fields you want to change. Requires write permission on the target calendar. Changing the attendees list on a service-account-connected calendar is rejected; reconnect the account via OAuth if you need to modify attendees.
calendarIdstringoptionalCalendar ID. Omit for default.eventIdstringrequiredThe event ID to update.summarystringoptionalNew event title.descriptionstringoptionalNew event description.locationstringoptionalNew event location.startDateTimestringoptionalNew start date/time (ISO 8601). For timed events.endDateTimestringoptionalNew end date/time (ISO 8601). For timed events.startDatestringoptionalNew start date for all-day events (YYYY-MM-DD).endDatestringoptionalNew end date for all-day events (YYYY-MM-DD, exclusive).timeZonestringoptionalTime zone.statusstringoptional"confirmed", "tentative", or "cancelled".remindersobjectoptionalUse {useDefault: false, overrides: []} to suppress all reminders.transparencystringoptional"opaque" (busy) or "transparent" (free).visibilitystringoptional"default", "public", "private", or "confidential".colorIdstringoptionalColor ID (1-11).attendeesstring[]optionalReplaces existing attendees.recurrencestring[]optionalRRULE format.{
"tool": "update_event",
"arguments": {
"eventId": "abc123def456",
"reminders": {
"useDefault": false,
"overrides": []
},
"transparency": "transparent"
}
}Updated event object.
batch_update_eventsUpdate multiple calendar events in one call. Each update is a partial patch. Max 50 events per call. Events are updated concurrently.
calendarIdstringoptionalCalendar ID. Omit for default. Applies to all events in the batch.updatesarrayrequiredArray of update objects (max 50). Each must include eventId plus fields to change. Supports: summary, description, location, startDateTime, endDateTime, startDate, endDate, timeZone, status, reminders, transparency, visibility, colorId.{
"tool": "batch_update_events",
"arguments": {
"updates": [
{
"eventId": "event1",
"reminders": {
"useDefault": false,
"overrides": []
},
"transparency": "transparent"
},
{
"eventId": "event2",
"reminders": {
"useDefault": false,
"overrides": []
},
"transparency": "transparent"
},
{
"eventId": "event3",
"colorId": "5",
"summary": "Updated Title"
}
]
}
}Summary: "X succeeded, Y failed" with event IDs. Failed events include error messages.
delete_eventDelete a calendar event.
calendarIdstringoptionalCalendar ID. Omit for default.eventIdstringrequiredThe event ID to delete.{
"tool": "delete_event",
"arguments": {
"eventId": "abc123def456"
}
}Confirmation message.
quick_add_eventCreate an event from natural language text. Google parses the text to extract date, time, title, and location.
calendarIdstringoptionalCalendar ID. Omit for default.textstringrequiredNatural language event description, e.g. "Lunch with Alice tomorrow at noon at Cafe Rio".{
"tool": "quick_add_event",
"arguments": {
"text": "Dentist appointment Friday at 2pm"
}
}Created event object.
list_calendarsList every calendar this API key can access across every connected Google account, with its enabled flag, per-calendar read/write permissions, and which kind of connection backs it (OAuth or service account).
{
"tool": "list_calendars",
"arguments": {}
}Array of { id, summary, enabled, canRead, canWrite, connectionKind }. Use this to discover what the key is allowed to do before attempting a tool call.
find_free_timeQuery free/busy information for one or more calendars in a time range.
calendarIdsstring[]optionalCalendar IDs to check. Omit for default.timeMinstringrequiredStart of time range (ISO 8601).timeMaxstringrequiredEnd of time range (ISO 8601).{
"tool": "find_free_time",
"arguments": {
"timeMin": "2026-04-21T08:00:00-07:00",
"timeMax": "2026-04-21T18:00:00-07:00"
}
}Array of busy slots per calendar with start/end times.
manage_attendeesAdd or remove attendees from an existing event without replacing the full attendee list.
calendarIdstringoptionalCalendar ID. Omit for default.eventIdstringrequiredThe event ID.addAttendeesstring[]optionalEmail addresses to add.removeAttendeesstring[]optionalEmail addresses to remove.{
"tool": "manage_attendees",
"arguments": {
"eventId": "abc123def456",
"addAttendees": [
"charlie@example.com"
],
"removeAttendees": [
"dave@example.com"
]
}
}Updated event object.
{
"tool": "update_event",
"arguments": {
"eventId": "EVENT_ID",
"reminders": {
"useDefault": false,
"overrides": []
}
}
}{
"tool": "update_event",
"arguments": {
"eventId": "EVENT_ID",
"transparency": "transparent"
}
}{
"tool": "batch_update_events",
"arguments": {
"updates": [
{
"eventId": "event1",
"reminders": {
"useDefault": false,
"overrides": []
}
},
{
"eventId": "event2",
"reminders": {
"useDefault": false,
"overrides": []
}
}
]
}
}{
"tool": "create_event",
"arguments": {
"summary": "🏨 Hilton Downtown",
"startDate": "2026-04-15",
"endDate": "2026-04-18",
"description": "Confirmation: ABC123\nCheck-in: 3pm\nCheck-out: 11am",
"reminders": {
"useDefault": false,
"overrides": []
},
"transparency": "transparent"
}
}{
"tool": "list_events",
"arguments": {
"timeMin": "2026-04-01T00:00:00Z",
"timeMax": "2026-04-30T23:59:59Z",
"maxResults": 500
}
}