Skip to main content
Glama

create_event

Schedule events in Google Calendar by specifying details like time, location, and attendees. Optionally include Google Meet, reminders, attachments, and custom timezones.

Instructions

Creates a new event.

Args: user_google_email (str): The user's Google email address. Required. summary (str): Event title. start_time (str): Start time (RFC3339, e.g., "2023-10-27T10:00:00-07:00" or "2023-10-27" for all-day). end_time (str): End time (RFC3339, e.g., "2023-10-27T11:00:00-07:00" or "2023-10-28" for all-day). calendar_id (str): Calendar ID (default: 'primary'). description (Optional[str]): Event description. location (Optional[str]): Event location. attendees (Optional[List[str]]): Attendee email addresses. timezone (Optional[str]): Timezone (e.g., "America/New_York"). attachments (Optional[List[str]]): List of Google Drive file URLs or IDs to attach to the event. add_google_meet (bool): Whether to add a Google Meet video conference to the event. Defaults to False. reminders (Optional[Union[str, List[Dict[str, Any]]]]): JSON string or list of reminder objects. Each should have 'method' ("popup" or "email") and 'minutes' (0-40320). Max 5 reminders. Example: '[{"method": "popup", "minutes": 15}]' or [{"method": "popup", "minutes": 15}] use_default_reminders (bool): Whether to use calendar's default reminders. If False, uses custom reminders. Defaults to True.

Returns: str: Confirmation message of the successful event creation with event link.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
add_google_meetNo
attachmentsNo
attendeesNo
calendar_idNoprimary
descriptionNo
end_timeYes
locationNo
remindersNo
start_timeYes
summaryYes
timezoneNo
use_default_remindersNo
user_google_emailYes

Implementation Reference

  • The main handler function that executes the create_event tool logic. It constructs the event body from parameters, handles special features like attachments, Google Meet conference, custom reminders, and inserts the event into the specified Google Calendar using the Google API.
    async def create_event( service, user_google_email: str, summary: str, start_time: str, end_time: str, calendar_id: str = "primary", description: Optional[str] = None, location: Optional[str] = None, attendees: Optional[List[str]] = None, timezone: Optional[str] = None, attachments: Optional[List[str]] = None, add_google_meet: bool = False, reminders: Optional[Union[str, List[Dict[str, Any]]]] = None, use_default_reminders: bool = True, ) -> str: """ Creates a new event. Args: user_google_email (str): The user's Google email address. Required. summary (str): Event title. start_time (str): Start time (RFC3339, e.g., "2023-10-27T10:00:00-07:00" or "2023-10-27" for all-day). end_time (str): End time (RFC3339, e.g., "2023-10-27T11:00:00-07:00" or "2023-10-28" for all-day). calendar_id (str): Calendar ID (default: 'primary'). description (Optional[str]): Event description. location (Optional[str]): Event location. attendees (Optional[List[str]]): Attendee email addresses. timezone (Optional[str]): Timezone (e.g., "America/New_York"). attachments (Optional[List[str]]): List of Google Drive file URLs or IDs to attach to the event. add_google_meet (bool): Whether to add a Google Meet video conference to the event. Defaults to False. reminders (Optional[Union[str, List[Dict[str, Any]]]]): JSON string or list of reminder objects. Each should have 'method' ("popup" or "email") and 'minutes' (0-40320). Max 5 reminders. Example: '[{"method": "popup", "minutes": 15}]' or [{"method": "popup", "minutes": 15}] use_default_reminders (bool): Whether to use calendar's default reminders. If False, uses custom reminders. Defaults to True. Returns: str: Confirmation message of the successful event creation with event link. """ logger.info( f"[create_event] Invoked. Email: '{user_google_email}', Summary: {summary}" ) logger.info(f"[create_event] Incoming attachments param: {attachments}") # If attachments value is a string, split by comma and strip whitespace if attachments and isinstance(attachments, str): attachments = [a.strip() for a in attachments.split(',') if a.strip()] logger.info(f"[create_event] Parsed attachments list from string: {attachments}") event_body: Dict[str, Any] = { "summary": summary, "start": ( {"date": start_time} if "T" not in start_time else {"dateTime": start_time} ), "end": ( {"date": end_time} if "T" not in end_time else {"dateTime": end_time} ), } if location: event_body["location"] = location if description: event_body["description"] = description if timezone: if "dateTime" in event_body["start"]: event_body["start"]["timeZone"] = timezone if "dateTime" in event_body["end"]: event_body["end"]["timeZone"] = timezone if attendees: event_body["attendees"] = [{"email": email} for email in attendees] # Handle reminders if reminders is not None or not use_default_reminders: # If custom reminders are provided, automatically disable default reminders effective_use_default = use_default_reminders and reminders is None reminder_data = { "useDefault": effective_use_default } if reminders is not None: validated_reminders = _parse_reminders_json(reminders, "create_event") if validated_reminders: reminder_data["overrides"] = validated_reminders logger.info(f"[create_event] Added {len(validated_reminders)} custom reminders") if use_default_reminders: logger.info("[create_event] Custom reminders provided - disabling default reminders") event_body["reminders"] = reminder_data if add_google_meet: request_id = str(uuid.uuid4()) event_body["conferenceData"] = { "createRequest": { "requestId": request_id, "conferenceSolutionKey": { "type": "hangoutsMeet" } } } logger.info(f"[create_event] Adding Google Meet conference with request ID: {request_id}") if attachments: # Accept both file URLs and file IDs. If a URL, extract the fileId. event_body["attachments"] = [] drive_service = None try: drive_service = service._http and build("drive", "v3", http=service._http) except Exception as e: logger.warning(f"Could not build Drive service for MIME type lookup: {e}") for att in attachments: file_id = None if att.startswith("https://"): # Match /d/<id>, /file/d/<id>, ?id=<id> match = re.search(r"(?:/d/|/file/d/|id=)([\w-]+)", att) file_id = match.group(1) if match else None logger.info(f"[create_event] Extracted file_id '{file_id}' from attachment URL '{att}'") else: file_id = att logger.info(f"[create_event] Using direct file_id '{file_id}' for attachment") if file_id: file_url = f"https://drive.google.com/open?id={file_id}" mime_type = "application/vnd.google-apps.drive-sdk" title = "Drive Attachment" # Try to get the actual MIME type and filename from Drive if drive_service: try: file_metadata = await asyncio.to_thread( lambda: drive_service.files().get(fileId=file_id, fields="mimeType,name").execute() ) mime_type = file_metadata.get("mimeType", mime_type) filename = file_metadata.get("name") if filename: title = filename logger.info(f"[create_event] Using filename '{filename}' as attachment title") else: logger.info("[create_event] No filename found, using generic title") except Exception as e: logger.warning(f"Could not fetch metadata for file {file_id}: {e}") event_body["attachments"].append({ "fileUrl": file_url, "title": title, "mimeType": mime_type, }) created_event = await asyncio.to_thread( lambda: service.events().insert( calendarId=calendar_id, body=event_body, supportsAttachments=True, conferenceDataVersion=1 if add_google_meet else 0 ).execute() ) else: created_event = await asyncio.to_thread( lambda: service.events().insert( calendarId=calendar_id, body=event_body, conferenceDataVersion=1 if add_google_meet else 0 ).execute() ) link = created_event.get("htmlLink", "No link available") confirmation_message = f"Successfully created event '{created_event.get('summary', summary)}' for {user_google_email}. Link: {link}" # Add Google Meet information if conference was created if add_google_meet and "conferenceData" in created_event: conference_data = created_event["conferenceData"] if "entryPoints" in conference_data: for entry_point in conference_data["entryPoints"]: if entry_point.get("entryPointType") == "video": meet_link = entry_point.get("uri", "") if meet_link: confirmation_message += f" Google Meet: {meet_link}" break logger.info( f"Event created successfully for {user_google_email}. ID: {created_event.get('id')}, Link: {link}" ) return confirmation_message
  • The @server.tool() decorator registers the create_event function as an MCP tool, with additional decorators for error handling and authentication.
    @server.tool()
  • Helper utility to parse and validate custom reminders input (JSON string or list) used in create_event for setting event reminders.
    def _parse_reminders_json(reminders_input: Optional[Union[str, List[Dict[str, Any]]]], function_name: str) -> List[Dict[str, Any]]: """ Parse reminders from JSON string or list object and validate them. Args: reminders_input: JSON string containing reminder objects or list of reminder objects function_name: Name of calling function for logging Returns: List of validated reminder objects """ if not reminders_input: return [] # Handle both string (JSON) and list inputs if isinstance(reminders_input, str): try: reminders = json.loads(reminders_input) if not isinstance(reminders, list): logger.warning(f"[{function_name}] Reminders must be a JSON array, got {type(reminders).__name__}") return [] except json.JSONDecodeError as e: logger.warning(f"[{function_name}] Invalid JSON for reminders: {e}") return [] elif isinstance(reminders_input, list): reminders = reminders_input else: logger.warning(f"[{function_name}] Reminders must be a JSON string or list, got {type(reminders_input).__name__}") return [] # Validate reminders if len(reminders) > 5: logger.warning(f"[{function_name}] More than 5 reminders provided, truncating to first 5") reminders = reminders[:5] validated_reminders = [] for reminder in reminders: if not isinstance(reminder, dict) or "method" not in reminder or "minutes" not in reminder: logger.warning(f"[{function_name}] Invalid reminder format: {reminder}, skipping") continue method = reminder["method"].lower() if method not in ["popup", "email"]: logger.warning(f"[{function_name}] Invalid reminder method '{method}', must be 'popup' or 'email', skipping") continue minutes = reminder["minutes"] if not isinstance(minutes, int) or minutes < 0 or minutes > 40320: logger.warning(f"[{function_name}] Invalid reminder minutes '{minutes}', must be integer 0-40320, skipping") continue validated_reminders.append({ "method": method, "minutes": minutes }) return validated_reminders
  • The docstring provides the input schema and descriptions for the create_event tool parameters.
    """ Creates a new event. Args: user_google_email (str): The user's Google email address. Required. summary (str): Event title. start_time (str): Start time (RFC3339, e.g., "2023-10-27T10:00:00-07:00" or "2023-10-27" for all-day). end_time (str): End time (RFC3339, e.g., "2023-10-27T11:00:00-07:00" or "2023-10-28" for all-day). calendar_id (str): Calendar ID (default: 'primary'). description (Optional[str]): Event description. location (Optional[str]): Event location. attendees (Optional[List[str]]): Attendee email addresses. timezone (Optional[str]): Timezone (e.g., "America/New_York"). attachments (Optional[List[str]]): List of Google Drive file URLs or IDs to attach to the event. add_google_meet (bool): Whether to add a Google Meet video conference to the event. Defaults to False. reminders (Optional[Union[str, List[Dict[str, Any]]]]): JSON string or list of reminder objects. Each should have 'method' ("popup" or "email") and 'minutes' (0-40320). Max 5 reminders. Example: '[{"method": "popup", "minutes": 15}]' or [{"method": "popup", "minutes": 15}] use_default_reminders (bool): Whether to use calendar's default reminders. If False, uses custom reminders. Defaults to True. Returns: str: Confirmation message of the successful event creation with event link. """

Other Tools

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/ZatesloFL/google_workspace_mcp'

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