MewCP Google Calendar MCP Server
Hosted, Stateless & Multitenant Google Calendar MCP server enables AI assistants to manage calendars, events, schedules, and availability through Google Calendar.
Documentation
Schedule smarter - create, search, and manage Google Calendar events through AI.
A Model Context Protocol (MCP) server that exposes Google Calendar's API for creating, reading, updating, and deleting events and calendars.
Overview
The Google Calendar MCP Server provides full calendar management capabilities:
- Create, update, delete, and search events across any calendar
- Manage multiple calendars — list, create, or delete them
- Query free/busy availability, recurring events, and upcoming schedules
Perfect for:
- Scheduling and rescheduling meetings via AI assistants
- Automating event creation and calendar organization workflows
- Querying availability and surfacing upcoming events in chat interfaces
Tools
list_calendars — List all calendars accessible by the user
Returns all calendars in the authenticated user's Google Calendar account.
Inputs:
(none)
Output:
{
"count": 3,
"calendars": [{ "id": "primary", "summary": "My Calendar", ... }]
}
get_calendar — Get details of a specific calendar
Fetches metadata for a single calendar by its ID.
Inputs:
- `calendar_id` (string, optional) — Calendar ID to retrieve. Defaults to "primary"
Output:
{
"id": "primary",
"summary": "My Calendar",
"timeZone": "America/New_York"
}
create_calendar — Create a new calendar
Creates a new Google Calendar in the user's account.
Inputs:
- `summary` (string, required) — Name of the new calendar
- `description` (string, optional) — Description of the calendar
- `timezone` (string, optional) — Timezone string (e.g. "America/New_York"). Defaults to "UTC"
Output:
{
"message": "Calendar created successfully",
"calendar": { "id": "...", "summary": "Work", ... }
}
delete_calendar — Delete a calendar
Permanently deletes a calendar by its ID.
Inputs:
- `calendar_id` (string, required) — ID of the calendar to delete
Output:
{
"message": "Calendar cal123 deleted successfully"
}
list_events — List events from a calendar within a time range
Returns events from a calendar, optionally filtered by time range and search query. Defaults to events from now onwards if no time range is specified.
Inputs:
- `calendar_id` (string, optional) — Calendar to query. Defaults to "primary"
- `max_results` (integer, optional) — Maximum number of events to return. Defaults to 10
- `time_min` (string, optional) — Start of time range in ISO 8601 format (e.g. "2026-01-08T00:00:00Z")
- `time_max` (string, optional) — End of time range in ISO 8601 format
- `query` (string, optional) — Free-text search query to filter events
Output:
{
"count": 2,
"events": [{ "id": "...", "summary": "Team Standup", ... }]
}
get_event — Get details of a specific event
Fetches full details for a single event by its ID.
Inputs:
- `event_id` (string, required) — ID of the event to retrieve
- `calendar_id` (string, optional) — Calendar containing the event. Defaults to "primary"
Output:
{
"id": "abc123",
"summary": "Team Standup",
"start": { "dateTime": "2026-01-08T09:00:00Z" },
...
}
create_event — Create a new calendar event
Creates a new event on the specified calendar with full details including attendees.
Inputs:
- `summary` (string, required) — Event title
- `start_time` (string, required) — Start time in ISO 8601 format (e.g. "2026-01-08T14:30:00")
- `end_time` (string, required) — End time in ISO 8601 format
- `calendar_id` (string, optional) — Target calendar. Defaults to "primary"
- `description` (string, optional) — Event description
- `location` (string, optional) — Event location
- `attendees` (list[string], optional) — List of attendee email addresses
- `timezone` (string, optional) — Timezone for start/end times (e.g. "America/New_York"). Defaults to "UTC"
Output:
{
"message": "Event created successfully",
"event": { "id": "...", "summary": "Lunch", ... }
}
create_quick_event — Create an event using natural language text
Creates a calendar event from a plain-text description (e.g. "Lunch with John tomorrow at 12pm").
Inputs:
- `text` (string, required) — Natural language event description
- `calendar_id` (string, optional) — Target calendar. Defaults to "primary"
Output:
{
"message": "Event created successfully",
"event": { "id": "...", "summary": "Lunch with John", ... }
}
update_event — Update an existing calendar event
Updates one or more fields of an existing event. Only provided fields are changed; others are preserved.
Inputs:
- `event_id` (string, required) — ID of the event to update
- `calendar_id` (string, optional) — Calendar containing the event. Defaults to "primary"
- `summary` (string, optional) — New event title
- `start_time` (string, optional) — New start time in ISO 8601 format
- `end_time` (string, optional) — New end time in ISO 8601 format
- `description` (string, optional) — New event description
- `location` (string, optional) — New event location
- `timezone` (string, optional) — Timezone for updated times. Defaults to "UTC"
Output:
{
"message": "Event updated successfully",
"event": { "id": "...", ... }
}
delete_event — Delete a calendar event
Permanently deletes an event from the specified calendar.
Inputs:
- `event_id` (string, required) — ID of the event to delete
- `calendar_id` (string, optional) — Calendar containing the event. Defaults to "primary"
Output:
{
"message": "Event evt123 deleted successfully"
}
search_events — Search for events containing specific text
Searches across event titles, descriptions, and locations on a calendar.
Inputs:
- `query` (string, required) — Search text
- `calendar_id` (string, optional) — Calendar to search. Defaults to "primary"
- `max_results` (integer, optional) — Maximum results to return. Defaults to 10
Output:
{
"count": 1,
"events": [{ "id": "...", "summary": "Project Kickoff", ... }]
}
get_upcoming_events — Get upcoming events for the next N days
Returns events starting from now through a specified number of days ahead.
Inputs:
- `days` (integer, optional) — Number of days to look ahead. Defaults to 7
- `calendar_id` (string, optional) — Calendar to query. Defaults to "primary"
- `max_results` (integer, optional) — Maximum results to return. Defaults to 10
Output:
{
"count": 5,
"events": [{ "id": "...", "summary": "Weekly Sync", ... }]
}
get_todays_events — Get all events for today
Returns all events scheduled for the current calendar day.
Inputs:
- `calendar_id` (string, optional) — Calendar to query. Defaults to "primary"
Output:
{
"count": 3,
"events": [{ "id": "...", "summary": "Morning Standup", ... }]
}
add_attendees — Add attendees to an existing event
Adds one or more attendees to an event and sends them invitations.
Inputs:
- `event_id` (string, required) — ID of the event to update
- `attendee_emails` (list[string], required) — Email addresses to add
- `calendar_id` (string, optional) — Calendar containing the event. Defaults to "primary"
Output:
{
"message": "Attendees added successfully",
"event": { "id": "...", "attendees": [...], ... }
}
get_free_busy — Get free/busy information for calendars
Queries the free/busy schedule of one or more calendars within a time window.
Inputs:
- `time_min` (string, required) — Start of query window in ISO 8601 format with Z suffix (e.g. "2026-01-08T09:00:00Z")
- `time_max` (string, required) — End of query window in ISO 8601 format with Z suffix
- `calendar_ids` (list[string], optional) — List of calendar IDs to query. Defaults to ["primary"]
Output:
{
"calendars": {
"primary": { "busy": [{ "start": "...", "end": "..." }] }
}
}
move_event — Move an event to a different calendar
Moves an existing event from one calendar to another.
Inputs:
- `event_id` (string, required) — ID of the event to move
- `source_calendar_id` (string, required) — Calendar currently holding the event
- `destination_calendar_id`(string, required) — Calendar to move the event into
Output:
{
"message": "Event moved successfully",
"event": { "id": "...", ... }
}
create_recurring_event — Create a recurring calendar event
Creates an event that repeats on a schedule defined by an RRULE string.
Inputs:
- `summary` (string, required) — Event title
- `start_time` (string, required) — First occurrence start time in ISO 8601 format
- `end_time` (string, required) — First occurrence end time in ISO 8601 format
- `recurrence_rule` (string, required) — RRULE string (e.g. "RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR")
- `calendar_id` (string, optional) — Target calendar. Defaults to "primary"
- `description` (string, optional) — Event description
- `location` (string, optional) — Event location
- `timezone` (string, optional) — Timezone for event times. Defaults to "UTC"
Output:
{
"message": "Recurring event created successfully",
"event": { "id": "...", "recurrence": ["RRULE:FREQ=WEEKLY;..."], ... }
}
API Parameters Reference
Common Parameters
calendar_id— Google Calendar ID. Use"primary"for the user's default calendar, or a full calendar ID like"[email protected]"for others. Retrieve IDs vialist_calendars.max_results— Caps the number of items returned. Maximum accepted by the Google API is 2500.timezone— IANA timezone string (e.g."America/New_York","Europe/London"). Applied tostart_timeandend_timewhen creating or updating events.
Time Formats
Event times (create/update):
Format: YYYY-MM-DDTHH:MM:SS
Example: 2026-01-08T14:30:00
With timezone offset:
Example: 2026-01-08T14:30:00-05:00
Query range times (list/free-busy):
Format: YYYY-MM-DDTHH:MM:SSZ (UTC, Z suffix required)
Example: 2026-01-08T00:00:00Z
Recurrence rules (RRULE):
Daily: RRULE:FREQ=DAILY
Weekly Mon/Wed/Fri: RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR
Monthly on 15th: RRULE:FREQ=MONTHLY;BYMONTHDAY=15
Troubleshooting
Missing or Invalid Headers
- Cause: OAuth token not provided in request headers or incorrect format
- Solution:
- Verify
Authorization: Bearer YOUR_API_KEYandX-Mewcp-Credential-Id: CREDENTIAL-IDheaders are present - Check your credential is active in your MewCP account
- Verify
Insufficient Credits
- Cause: API calls have exceeded your request limits
- Solution:
- Check credit usage in your Curious Layer dashboard
- Upgrade to a paid plan or add credits for higher limits
- Contact support for credit adjustments
Credential Not Connected
- Cause: No Google account linked to your MewCP credential
- Solution:
- Go to Credentials in your MewCP dashboard
- Connect your Google account via OAuth
- Retry the request with the correct
X-Mewcp-Credential-Idheader
Malformed Request Payload
- Cause: JSON payload is invalid or missing required fields
- Solution:
- Validate JSON syntax before sending
- Ensure all required tool parameters are included
- Check parameter types match expected values
Server Not Found
- Cause: Incorrect server name in the API endpoint
- Solution:
- Verify endpoint format:
{server-name}/mcp/{tool-name} - Use correct server name from documentation
- Check available servers in your Curious Layer account
- Verify endpoint format:
Google Calendar API Error
- Cause: Upstream Google Calendar API returned an error
- Solution:
- Check Google Workspace service status at Google Status Dashboard
- Verify your Google account has the required Calendar permissions
- Review the error message for specific details
Resources
- Google Calendar API Documentation — Official API reference
- Google Calendar API Reference — Complete endpoint reference
- FastMCP Docs — FastMCP specification
- FastMCP Credentials — FastMCP Credentials package for credential handling