Skip to main content
Glama

Google Meet MCP Server

GoogleMeetAPI.js9.3 kB
/** * Google Meet API client that interacts with the Google Calendar API * to manage Google Meet meetings. */ import fs from 'fs/promises'; import path from 'path'; import { google } from 'googleapis'; class GoogleMeetAPI { /** * Initialize the Google Meet API client. * @param {string} credentialsPath - Path to the client_secret.json file * @param {string} tokenPath - Path to save/load the token.json file */ constructor(credentialsPath, tokenPath) { this.credentialsPath = credentialsPath; this.tokenPath = tokenPath; this.calendar = null; } /** * Initialize the API client with OAuth2 credentials. */ async initialize() { const credentials = JSON.parse(await fs.readFile(this.credentialsPath, 'utf8')); const { client_id, client_secret, redirect_uris } = credentials.web; const oAuth2Client = new google.auth.OAuth2( client_id, client_secret, redirect_uris[0] ); try { // Check if token exists and use it const token = JSON.parse(await fs.readFile(this.tokenPath, 'utf8')); oAuth2Client.setCredentials(token); // Check if token is expired and needs refresh if (token.expiry_date && token.expiry_date < Date.now()) { // Token is expired, refresh it const { credentials } = await oAuth2Client.refreshToken(token.refresh_token); await fs.writeFile(this.tokenPath, JSON.stringify(credentials)); oAuth2Client.setCredentials(credentials); } } catch (error) { throw new Error( "No valid credentials. Please run the setup script first to authorize access." ); } // Initialize the calendar API this.calendar = google.calendar({ version: 'v3', auth: oAuth2Client }); } /** * List upcoming Google Meet meetings. * @param {number} maxResults - Maximum number of results to return * @param {string} timeMin - Start time in ISO format * @param {string} timeMax - End time in ISO format * @returns {Promise<Array>} - List of meetings */ async listMeetings(maxResults = 10, timeMin = null, timeMax = null) { // Default timeMin to now if not provided if (!timeMin) { timeMin = new Date().toISOString(); } // Prepare parameters for the API call const params = { calendarId: 'primary', maxResults: maxResults, timeMin: timeMin, orderBy: 'startTime', singleEvents: true, conferenceDataVersion: 1 }; if (timeMax) { params.timeMax = timeMax; } try { const response = await this.calendar.events.list(params); const events = response.data.items || []; // Filter for events with conferenceData (Google Meet) const meetings = []; for (const event of events) { if (event.conferenceData) { const meeting = this._formatMeetingData(event); if (meeting) { meetings.push(meeting); } } } return meetings; } catch (error) { throw new Error(`Error listing meetings: ${error.message}`); } } /** * Get details of a specific Google Meet meeting. * @param {string} meetingId - ID of the meeting to retrieve * @returns {Promise<Object>} - Meeting details */ async getMeeting(meetingId) { try { const response = await this.calendar.events.get({ calendarId: 'primary', eventId: meetingId, conferenceDataVersion: 1 }); const event = response.data; if (!event.conferenceData) { throw new Error(`Event with ID ${meetingId} does not have Google Meet conferencing data`); } const meeting = this._formatMeetingData(event); if (!meeting) { throw new Error(`Failed to format meeting data for event ID ${meetingId}`); } return meeting; } catch (error) { throw new Error(`Error getting meeting: ${error.message}`); } } /** * Create a new Google Meet meeting. * @param {string} summary - Title of the meeting * @param {string} startTime - Start time in ISO format * @param {string} endTime - End time in ISO format * @param {string} description - Description for the meeting * @param {Array<string>} attendees - List of email addresses for attendees * @returns {Promise<Object>} - Created meeting details */ async createMeeting(summary, startTime, endTime, description = "", attendees = []) { // Prepare attendees list in the format required by the API const formattedAttendees = attendees.map(email => ({ email })); // Create the event with Google Meet conferencing const event = { summary: summary, description: description, start: { dateTime: startTime, timeZone: 'UTC', }, end: { dateTime: endTime, timeZone: 'UTC', }, attendees: formattedAttendees, conferenceData: { createRequest: { requestId: `meet-${Date.now()}` } } }; try { const response = await this.calendar.events.insert({ calendarId: 'primary', conferenceDataVersion: 1, resource: event }); const createdEvent = response.data; if (!createdEvent.conferenceData) { throw new Error("Failed to create Google Meet conferencing data"); } const meeting = this._formatMeetingData(createdEvent); if (!meeting) { throw new Error("Failed to format meeting data for newly created event"); } return meeting; } catch (error) { throw new Error(`Error creating meeting: ${error.message}`); } } /** * Update an existing Google Meet meeting. * @param {string} meetingId - ID of the meeting to update * @param {Object} updateData - Fields to update * @returns {Promise<Object>} - Updated meeting details */ async updateMeeting(meetingId, { summary, description, startTime, endTime, attendees } = {}) { try { // First, get the existing event const response = await this.calendar.events.get({ calendarId: 'primary', eventId: meetingId }); const event = response.data; // Update the fields that were provided if (summary !== undefined) { event.summary = summary; } if (description !== undefined) { event.description = description; } if (startTime !== undefined) { event.start.dateTime = startTime; } if (endTime !== undefined) { event.end.dateTime = endTime; } if (attendees !== undefined) { event.attendees = attendees.map(email => ({ email })); } // Make the API call to update the event const updateResponse = await this.calendar.events.update({ calendarId: 'primary', eventId: meetingId, conferenceDataVersion: 1, resource: event }); const updatedEvent = updateResponse.data; if (!updatedEvent.conferenceData) { throw new Error("Updated event does not have Google Meet conferencing data"); } const meeting = this._formatMeetingData(updatedEvent); if (!meeting) { throw new Error("Failed to format meeting data for updated event"); } return meeting; } catch (error) { throw new Error(`Error updating meeting: ${error.message}`); } } /** * Delete a Google Meet meeting. * @param {string} meetingId - ID of the meeting to delete * @returns {Promise<boolean>} - True if deleted successfully */ async deleteMeeting(meetingId) { try { await this.calendar.events.delete({ calendarId: 'primary', eventId: meetingId }); return true; } catch (error) { throw new Error(`Error deleting meeting: ${error.message}`); } } /** * Format event data to meeting format. * @param {Object} event - Event data from Google Calendar API * @returns {Object|null} - Formatted meeting data or null */ _formatMeetingData(event) { if (!event.conferenceData) { return null; } // Extract the Google Meet link let meetLink = null; for (const entryPoint of event.conferenceData.entryPoints || []) { if (entryPoint.entryPointType === 'video') { meetLink = entryPoint.uri; break; } } if (!meetLink) { return null; } // Format attendees const attendees = (event.attendees || []).map(attendee => ({ email: attendee.email, response_status: attendee.responseStatus })); // Build the formatted meeting data const meeting = { id: event.id, summary: event.summary || '', description: event.description || '', meet_link: meetLink, start_time: event.start?.dateTime || event.start?.date, end_time: event.end?.dateTime || event.end?.date, attendees: attendees, creator: event.creator?.email, organizer: event.organizer?.email, created: event.created, updated: event.updated, }; return meeting; } } export default GoogleMeetAPI;

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/cool-man-vk/google-meet-mcp-server'

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