Skip to main content
Glama
ZatesloFL

Google Workspace MCP Server

by ZatesloFL

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.
    """
Install Server

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