MewCP Google Calendar MCP

Servidor MCP de Google Calendar alojado, sin estado y multiinquilino que permite a los asistentes de IA gestionar calendarios, eventos, horarios y disponibilidad a través de Google Calendar.

Documentación

Programa de forma más inteligente: crea, busca y gestiona eventos de Google Calendar mediante IA.

Un servidor de Model Context Protocol (MCP) que expone la API de Google Calendar para crear, leer, actualizar y eliminar eventos y calendarios.

Descripción general

El servidor MCP de Google Calendar ofrece una gestión completa del calendario directamente desde flujos de trabajo de IA:

  • Lista, busca y recupera eventos con filtros avanzados por rango de tiempo, texto y recurrencia
  • Crea eventos puntuales, de día completo, rápidos y recurrentes con asistentes, recordatorios y enlaces de Meet
  • Actualiza eventos y gestiona asistentes, y obtén el estado antes/después en una sola respuesta
  • Consulta bloques de disponibilidad (free/busy) en varios calendarios para encontrar espacios libres sin conflictos

Ideal para:

  • Asistentes de IA que programan, reprograman y gestionan reuniones en nombre de los usuarios
  • Automatización de flujos de trabajo que lee el estado del calendario para activar acciones basadas en el tiempo
  • Agentes que coordinan la disponibilidad y envían invitaciones entre equipos

Herramientas

Eventos — Lectura

list_events — Lista eventos de un calendario

Lista eventos de un calendario dentro de un rango de tiempo opcional. Devuelve los eventos en orden de hora de inicio. Los eventos recurrentes se expanden en instancias individuales. Usa ISO 8601 para time_min/time_max: 'YYYY-MM-DDTHH:MM:SSZ' (p. ej., '2026-01-08T00:00:00Z'). Si no se especifica time_min, el valor predeterminado son los eventos desde ahora en adelante.

Entradas:

- `calendar_id` (string, optional, default: "primary") — Calendar ID. Use 'primary' for the user's main calendar
- `max_results` (int, optional, default: 10) — Maximum number of events to return (1–2500)
- `time_min` (string, optional, default: "") — Start of time range in ISO 8601 format, e.g. '2026-01-08T00:00:00Z'. Defaults to now
- `time_max` (string, optional, default: "") — End of time range in ISO 8601 format, e.g. '2026-01-15T23:59:59Z'. Omit for open-ended
- `query` (string, optional, default: "") — Free-text search query to filter events by title, description, or location
- `show_deleted` (bool, optional, default: false) — Include cancelled events in results
- `page_token` (string, optional, default: "") — Pagination token from a previous response's next_page_token to fetch the next page

Esquema de salida data:

{
  count: number;
  events: {
    id: string;
    summary: string | null;
    start: { date: string | null; dateTime: string | null; timeZone: string | null; };
    end: { date: string | null; dateTime: string | null; timeZone: string | null; };
    status: string | null;
    htmlLink: string | null;
    created: string | null;
    updated: string | null;
    description: string | null;
    location: string | null;
    colorId: string | null;
    creator: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    organizer: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    recurrence: string[] | null;
    recurringEventId: string | null;
    originalStartTime: { date: string | null; dateTime: string | null; timeZone: string | null; } | null;
    transparency: string | null;
    visibility: string | null;
    iCalUID: string | null;
    sequence: number | null;
    attendees: {
      email: string;
      id: string | null;
      displayName: string | null;
      organizer: boolean | null;
      self: boolean | null;
      resource: boolean | null;
      optional: boolean | null;
      responseStatus: string | null;
      comment: string | null;
      additionalGuests: number | null;
    }[] | null;
    attendeesOmitted: boolean | null;
    guestsCanInviteOthers: boolean | null;
    guestsCanModify: boolean | null;
    guestsCanSeeOtherGuests: boolean | null;
    hangoutLink: string | null;
    conferenceData: object | null;
    reminders: { useDefault: boolean; overrides: { method: string; minutes: number; }[] | null; } | null;
    eventType: string | null;
  }[];
  next_page_token: string | null;
}
get_event — Obtiene un único evento por ID

Obtiene los detalles completos de un evento específico, incluidos asistentes, estados de RSVP, reglas de recurrencia, recordatorios e información de conferencias.

Entradas:

- `event_id` (string, required) — ID of the event to retrieve
- `calendar_id` (string, optional, default: "primary") — Calendar ID containing the event. Use 'primary' for the user's main calendar

Esquema de salida data:

{
  id: string;
  summary: string | null;
  start: { date: string | null; dateTime: string | null; timeZone: string | null; };
  end: { date: string | null; dateTime: string | null; timeZone: string | null; };
  status: string | null;
  htmlLink: string | null;
  created: string | null;
  updated: string | null;
  description: string | null;
  location: string | null;
  colorId: string | null;
  creator: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
  organizer: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
  recurrence: string[] | null;
  recurringEventId: string | null;
  originalStartTime: { date: string | null; dateTime: string | null; timeZone: string | null; } | null;
  transparency: string | null;
  visibility: string | null;
  iCalUID: string | null;
  sequence: number | null;
  attendees: {
    email: string;
    id: string | null;
    displayName: string | null;
    organizer: boolean | null;
    self: boolean | null;
    resource: boolean | null;
    optional: boolean | null;
    responseStatus: string | null;
    comment: string | null;
    additionalGuests: number | null;
  }[] | null;
  attendeesOmitted: boolean | null;
  guestsCanInviteOthers: boolean | null;
  guestsCanModify: boolean | null;
  guestsCanSeeOtherGuests: boolean | null;
  hangoutLink: string | null;
  conferenceData: object | null;
  reminders: { useDefault: boolean; overrides: { method: string; minutes: number; }[] | null; } | null;
  eventType: string | null;
}
search_events — Busca eventos por texto

Busca eventos por texto en títulos, descripciones y ubicaciones. Opcionalmente, limita la búsqueda a un rango de tiempo con time_min/time_max (ISO 8601, p. ej., '2026-01-08T00:00:00Z'). Sin un rango de tiempo, la búsqueda abarca todo el historial; usa siempre un rango de tiempo para calendarios grandes.

Entradas:

- `query` (string, required) — Text to search for in event titles, descriptions, and locations
- `calendar_id` (string, optional, default: "primary") — Calendar ID to search in. Use 'primary' for the user's main calendar
- `max_results` (int, optional, default: 10) — Maximum number of events to return (1–2500)
- `time_min` (string, optional, default: "") — Optional start of time range in ISO 8601 format, e.g. '2026-01-01T00:00:00Z'
- `time_max` (string, optional, default: "") — Optional end of time range in ISO 8601 format, e.g. '2026-12-31T23:59:59Z'
- `page_token` (string, optional, default: "") — Pagination token from a previous response's next_page_token to fetch the next page

Esquema de salida data:

{
  count: number;
  events: {
    id: string;
    summary: string | null;
    start: { date: string | null; dateTime: string | null; timeZone: string | null; };
    end: { date: string | null; dateTime: string | null; timeZone: string | null; };
    status: string | null;
    htmlLink: string | null;
    created: string | null;
    updated: string | null;
    description: string | null;
    location: string | null;
    colorId: string | null;
    creator: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    organizer: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    recurrence: string[] | null;
    recurringEventId: string | null;
    originalStartTime: { date: string | null; dateTime: string | null; timeZone: string | null; } | null;
    transparency: string | null;
    visibility: string | null;
    iCalUID: string | null;
    sequence: number | null;
    attendees: {
      email: string;
      id: string | null;
      displayName: string | null;
      organizer: boolean | null;
      self: boolean | null;
      resource: boolean | null;
      optional: boolean | null;
      responseStatus: string | null;
      comment: string | null;
      additionalGuests: number | null;
    }[] | null;
    attendeesOmitted: boolean | null;
    guestsCanInviteOthers: boolean | null;
    guestsCanModify: boolean | null;
    guestsCanSeeOtherGuests: boolean | null;
    hangoutLink: string | null;
    conferenceData: object | null;
    reminders: { useDefault: boolean; overrides: { method: string; minutes: number; }[] | null; } | null;
    eventType: string | null;
  }[];
  next_page_token: string | null;
}
get_upcoming_events — Obtiene eventos en los próximos N días

Obtiene eventos desde ahora hasta los próximos N días. Devuelve los eventos en orden de hora de inicio. Los eventos recurrentes se expanden en instancias individuales.

Entradas:

- `days` (int, optional, default: 7) — Number of days to look ahead from now
- `calendar_id` (string, optional, default: "primary") — Calendar ID to query. Use 'primary' for the user's main calendar
- `max_results` (int, optional, default: 10) — Maximum number of events to return (1–2500)

Esquema de salida data:

{
  count: number;
  events: {
    id: string;
    summary: string | null;
    start: { date: string | null; dateTime: string | null; timeZone: string | null; };
    end: { date: string | null; dateTime: string | null; timeZone: string | null; };
    status: string | null;
    htmlLink: string | null;
    created: string | null;
    updated: string | null;
    description: string | null;
    location: string | null;
    colorId: string | null;
    creator: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    organizer: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    recurrence: string[] | null;
    recurringEventId: string | null;
    originalStartTime: { date: string | null; dateTime: string | null; timeZone: string | null; } | null;
    transparency: string | null;
    visibility: string | null;
    iCalUID: string | null;
    sequence: number | null;
    attendees: {
      email: string;
      id: string | null;
      displayName: string | null;
      organizer: boolean | null;
      self: boolean | null;
      resource: boolean | null;
      optional: boolean | null;
      responseStatus: string | null;
      comment: string | null;
      additionalGuests: number | null;
    }[] | null;
    attendeesOmitted: boolean | null;
    guestsCanInviteOthers: boolean | null;
    guestsCanModify: boolean | null;
    guestsCanSeeOtherGuests: boolean | null;
    hangoutLink: string | null;
    conferenceData: object | null;
    reminders: { useDefault: boolean; overrides: { method: string; minutes: number; }[] | null; } | null;
    eventType: string | null;
  }[];
  next_page_token: string | null;
}
get_todays_events — Obtiene todos los eventos de hoy

Obtiene todos los eventos programados para hoy en la zona horaria indicada. Pasa la zona horaria local del usuario para obtener el día correcto (p. ej., 'America/New_York'). El valor predeterminado es UTC.

Entradas:

- `calendar_id` (string, optional, default: "primary") — Calendar ID to query. Use 'primary' for the user's main calendar
- `timezone` (string, optional, default: "UTC") — IANA timezone name to determine 'today', e.g. 'America/New_York'. Defaults to UTC

Esquema de salida data:

{
  count: number;
  events: {
    id: string;
    summary: string | null;
    start: { date: string | null; dateTime: string | null; timeZone: string | null; };
    end: { date: string | null; dateTime: string | null; timeZone: string | null; };
    status: string | null;
    htmlLink: string | null;
    created: string | null;
    updated: string | null;
    description: string | null;
    location: string | null;
    colorId: string | null;
    creator: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    organizer: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    recurrence: string[] | null;
    recurringEventId: string | null;
    originalStartTime: { date: string | null; dateTime: string | null; timeZone: string | null; } | null;
    transparency: string | null;
    visibility: string | null;
    iCalUID: string | null;
    sequence: number | null;
    attendees: {
      email: string;
      id: string | null;
      displayName: string | null;
      organizer: boolean | null;
      self: boolean | null;
      resource: boolean | null;
      optional: boolean | null;
      responseStatus: string | null;
      comment: string | null;
      additionalGuests: number | null;
    }[] | null;
    attendeesOmitted: boolean | null;
    guestsCanInviteOthers: boolean | null;
    guestsCanModify: boolean | null;
    guestsCanSeeOtherGuests: boolean | null;
    hangoutLink: string | null;
    conferenceData: object | null;
    reminders: { useDefault: boolean; overrides: { method: string; minutes: number; }[] | null; } | null;
    eventType: string | null;
  }[];
  next_page_token: string | null;
}
list_event_instances — Lista instancias de un evento recurrente

Lista todas las instancias individuales de un evento recurrente mediante su ID de evento maestro. Úsalo para ver cada ocurrencia de una serie recurrente; usa get_event o list_events para encontrar primero el ID del evento maestro. Las instancias incluyen recurringEventId (el ID maestro) y originalStartTime (la hora programada según la RRULE, que difiere de start si la instancia fue reprogramada). Opcionalmente, filtra por rango de tiempo para ver solo ocurrencias futuras o pasadas.

Entradas:

- `recurring_event_id` (string, required) — ID of the master recurring event whose instances to list
- `calendar_id` (string, optional, default: "primary") — Calendar ID containing the recurring event. Use 'primary' for the user's main calendar
- `max_results` (int, optional, default: 10) — Maximum number of instances to return (1–2500)
- `time_min` (string, optional, default: "") — Optional start of time range in ISO 8601 format, e.g. '2026-01-01T00:00:00Z'. Filters to instances starting at or after this time
- `time_max` (string, optional, default: "") — Optional end of time range in ISO 8601 format. Filters to instances starting before this time
- `show_deleted` (bool, optional, default: false) — Include cancelled instances in results
- `page_token` (string, optional, default: "") — Pagination token from a previous response's next_page_token to fetch the next page

Esquema de salida data:

{
  count: number;
  events: {
    id: string;
    summary: string | null;
    start: { date: string | null; dateTime: string | null; timeZone: string | null; };
    end: { date: string | null; dateTime: string | null; timeZone: string | null; };
    status: string | null;
    htmlLink: string | null;
    created: string | null;
    updated: string | null;
    description: string | null;
    location: string | null;
    colorId: string | null;
    creator: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    organizer: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    recurrence: string[] | null;
    recurringEventId: string | null;
    originalStartTime: { date: string | null; dateTime: string | null; timeZone: string | null; } | null;
    transparency: string | null;
    visibility: string | null;
    iCalUID: string | null;
    sequence: number | null;
    attendees: {
      email: string;
      id: string | null;
      displayName: string | null;
      organizer: boolean | null;
      self: boolean | null;
      resource: boolean | null;
      optional: boolean | null;
      responseStatus: string | null;
      comment: string | null;
      additionalGuests: number | null;
    }[] | null;
    attendeesOmitted: boolean | null;
    guestsCanInviteOthers: boolean | null;
    guestsCanModify: boolean | null;
    guestsCanSeeOtherGuests: boolean | null;
    hangoutLink: string | null;
    conferenceData: object | null;
    reminders: { useDefault: boolean; overrides: { method: string; minutes: number; }[] | null; } | null;
    eventType: string | null;
  }[];
  next_page_token: string | null;
}

Eventos — Escritura

create_event — Crea un nuevo evento de calendario

Crea un nuevo evento de calendario y, opcionalmente, invita a asistentes. Para eventos con hora, usa fecha y hora ISO 8601: '2026-01-08T14:30:00' con una zona horaria. Para eventos de día completo, establece is_all_day=True y usa el formato solo de fecha: '2026-01-08' — para eventos de día completo, end_time es exclusivo, por lo que un evento de un solo día el 8 de enero necesita end_time='2026-01-09'. Devuelve el evento creado con su ID.

Entradas:

- `summary` (string, required) — Event title
- `start_time` (string, required) — Start time: ISO 8601 datetime e.g. '2026-01-08T14:30:00', or date e.g. '2026-01-08' for all-day events
- `end_time` (string, required) — End time: ISO 8601 datetime or date. For all-day, end is exclusive: event on Jan 8 alone needs end_time='2026-01-09'
- `calendar_id` (string, optional, default: "primary") — Calendar ID to create the event in. Use 'primary' for the user's main calendar
- `description` (string, optional, default: "") — Event description or agenda
- `location` (string, optional, default: "") — Event location. Enables map directions and 'time to leave' alerts in Google Calendar
- `attendees` (list[string], optional, default: []) — Attendee email addresses. Invitation emails are sent per send_updates
- `timezone` (string, optional, default: "UTC") — IANA timezone for the event, e.g. 'America/New_York'. Ignored for all-day events
- `is_all_day` (bool, optional, default: false) — Set True for all-day events. Use date-only format (YYYY-MM-DD) for start_time and end_time
- `color_id` (string, optional, default: "") — Color ID 1–11 for the event. Empty uses the calendar's default color
- `visibility` (string, optional, default: "") — Event visibility: 'default', 'public', 'private', or 'confidential'. Empty uses calendar default
- `transparency` (string, optional, default: "") — Free/busy status: 'opaque' (user shows as busy, default) or 'transparent' (user shows as free/available during this event)
- `reminder_minutes` (int, optional, default: -1) — Minutes before event for a popup reminder (0–40320). Set -1 to use the calendar's default reminders
- `send_updates` (string, optional, default: "all") — Who receives invitation emails: 'all' (everyone), 'externalOnly' (non-Google users only), 'none' (no emails)
- `add_meet` (bool, optional, default: false) — Set True to automatically create a Google Meet video conference link for this event
- `optional_attendees` (list[string], optional, default: []) — Email addresses of optional attendees. These people are invited but their attendance is not required
- `guests_can_invite_others` (bool, optional, default: true) — Whether attendees can invite additional guests. Defaults to True per Google Calendar
- `guests_can_modify` (bool, optional, default: false) — Whether attendees can modify the event. Defaults to False

Esquema de salida data:

{
  id: string;
  summary: string | null;
  start: { date: string | null; dateTime: string | null; timeZone: string | null; };
  end: { date: string | null; dateTime: string | null; timeZone: string | null; };
  status: string | null;
  htmlLink: string | null;
  created: string | null;
  updated: string | null;
  description: string | null;
  location: string | null;
  colorId: string | null;
  creator: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
  organizer: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
  recurrence: string[] | null;
  recurringEventId: string | null;
  originalStartTime: { date: string | null; dateTime: string | null; timeZone: string | null; } | null;
  transparency: string | null;
  visibility: string | null;
  iCalUID: string | null;
  sequence: number | null;
  attendees: {
    email: string;
    id: string | null;
    displayName: string | null;
    organizer: boolean | null;
    self: boolean | null;
    resource: boolean | null;
    optional: boolean | null;
    responseStatus: string | null;
    comment: string | null;
    additionalGuests: number | null;
  }[] | null;
  attendeesOmitted: boolean | null;
  guestsCanInviteOthers: boolean | null;
  guestsCanModify: boolean | null;
  guestsCanSeeOtherGuests: boolean | null;
  hangoutLink: string | null;
  conferenceData: object | null;
  reminders: { useDefault: boolean; overrides: { method: string; minutes: number; }[] | null; } | null;
  eventType: string | null;
}
create_quick_event — Crea un evento a partir de lenguaje natural

Crea un evento a partir de una descripción de texto en lenguaje natural. Google Calendar analiza el texto para extraer título, fecha, hora y recurrencia. Ejemplos: 'Almuerzo con Sara mañana al mediodía', 'Reunión de equipo todos los lunes a las 9 a. m.'. Devuelve el evento creado. Para eventos complejos con asistentes o campos personalizados, usa create_event en su lugar.

Entradas:

- `text` (string, required) — Natural language event description, e.g. 'Dentist appointment next Friday at 3pm'
- `calendar_id` (string, optional, default: "primary") — Calendar ID to create the event in. Use 'primary' for the user's main calendar
- `send_updates` (string, optional, default: "all") — Who receives invitation emails: 'all', 'externalOnly', or 'none'

Esquema de salida data:

{
  id: string;
  summary: string | null;
  start: { date: string | null; dateTime: string | null; timeZone: string | null; };
  end: { date: string | null; dateTime: string | null; timeZone: string | null; };
  status: string | null;
  htmlLink: string | null;
  created: string | null;
  updated: string | null;
  description: string | null;
  location: string | null;
  colorId: string | null;
  creator: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
  organizer: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
  recurrence: string[] | null;
  recurringEventId: string | null;
  originalStartTime: { date: string | null; dateTime: string | null; timeZone: string | null; } | null;
  transparency: string | null;
  visibility: string | null;
  iCalUID: string | null;
  sequence: number | null;
  attendees: {
    email: string;
    id: string | null;
    displayName: string | null;
    organizer: boolean | null;
    self: boolean | null;
    resource: boolean | null;
    optional: boolean | null;
    responseStatus: string | null;
    comment: string | null;
    additionalGuests: number | null;
  }[] | null;
  attendeesOmitted: boolean | null;
  guestsCanInviteOthers: boolean | null;
  guestsCanModify: boolean | null;
  guestsCanSeeOtherGuests: boolean | null;
  hangoutLink: string | null;
  conferenceData: object | null;
  reminders: { useDefault: boolean; overrides: { method: string; minutes: number; }[] | null; } | null;
  eventType: string | null;
}
create_recurring_event — Crea un evento recurrente con una RRULE

Crea un evento de calendario recurrente usando un patrón de recurrencia RRULE. recurrence_rule debe comenzar con 'RRULE:' seguido de los parámetros RFC 5545. Ejemplos: 'RRULE:FREQ=DAILY;COUNT=5', 'RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR', 'RRULE:FREQ=MONTHLY;BYMONTHDAY=15', 'RRULE:FREQ=YEARLY'. Devuelve el evento maestro recurrente; Google Calendar expande las instancias individuales.

Entradas:

- `summary` (string, required) — Event title
- `start_time` (string, required) — Start time of the first occurrence in ISO 8601 format, e.g. '2026-01-08T14:30:00'
- `end_time` (string, required) — End time of the first occurrence in ISO 8601 format, e.g. '2026-01-08T15:30:00'
- `recurrence_rule` (string, required) — RRULE string starting with 'RRULE:', e.g. 'RRULE:FREQ=WEEKLY;BYDAY=MO'
- `calendar_id` (string, optional, default: "primary") — Calendar ID to create the event in. Use 'primary' for the user's main calendar
- `description` (string, optional, default: "") — Event description or agenda
- `location` (string, optional, default: "") — Event location
- `attendees` (list[string], optional, default: []) — Attendee email addresses. Invitation emails are sent per send_updates
- `timezone` (string, optional, default: "UTC") — IANA timezone for the event, e.g. 'America/New_York'
- `transparency` (string, optional, default: "") — Free/busy status: 'opaque' (shows as busy, default) or 'transparent' (shows as free)
- `reminder_minutes` (int, optional, default: -1) — Minutes before each occurrence for a popup reminder (0–40320). Set -1 to use calendar default
- `send_updates` (string, optional, default: "all") — Who receives invitation emails: 'all', 'externalOnly', or 'none'
- `add_meet` (bool, optional, default: false) — Set True to automatically create a Google Meet video conference link for this event
- `optional_attendees` (list[string], optional, default: []) — Email addresses of optional attendees. These people are invited but their attendance is not required
- `guests_can_invite_others` (bool, optional, default: true) — Whether attendees can invite additional guests. Defaults to True per Google Calendar
- `guests_can_modify` (bool, optional, default: false) — Whether attendees can modify the event. Defaults to False

Esquema de salida data:

{
  id: string;
  summary: string | null;
  start: { date: string | null; dateTime: string | null; timeZone: string | null; };
  end: { date: string | null; dateTime: string | null; timeZone: string | null; };
  status: string | null;
  htmlLink: string | null;
  created: string | null;
  updated: string | null;
  description: string | null;
  location: string | null;
  colorId: string | null;
  creator: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
  organizer: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
  recurrence: string[] | null;
  recurringEventId: string | null;
  originalStartTime: { date: string | null; dateTime: string | null; timeZone: string | null; } | null;
  transparency: string | null;
  visibility: string | null;
  iCalUID: string | null;
  sequence: number | null;
  attendees: {
    email: string;
    id: string | null;
    displayName: string | null;
    organizer: boolean | null;
    self: boolean | null;
    resource: boolean | null;
    optional: boolean | null;
    responseStatus: string | null;
    comment: string | null;
    additionalGuests: number | null;
  }[] | null;
  attendeesOmitted: boolean | null;
  guestsCanInviteOthers: boolean | null;
  guestsCanModify: boolean | null;
  guestsCanSeeOtherGuests: boolean | null;
  hangoutLink: string | null;
  conferenceData: object | null;
  reminders: { useDefault: boolean; overrides: { method: string; minutes: number; }[] | null; } | null;
  eventType: string | null;
}
update_event — Actualiza un evento existente

Actualiza un evento de calendario existente. Solo se cambian los campos que proporciones; deja un campo vacío para mantener su valor actual. Primero obtiene el evento actual, aplica los cambios y luego guarda. Usa ISO 8601 para las horas: 'YYYY-MM-DDTHH:MM:SS'. Para eventos recurrentes: pasa el ID del evento maestro recurrente para cambiar todas las instancias, o un ID de instancia específico para cambiar solo esa ocurrencia. ADVERTENCIA: no actualices instancias individuales una por una para cambiar toda la serie; actualiza el evento maestro en su lugar. Modificar instancias individualmente crea excepciones que saturan el calendario y generan notificaciones excesivas. Para cancelar una sola instancia sin afectar al resto de la serie, establece status='cancelled'.

Entradas:

- `event_id` (string, required) — ID of the event to update. For recurring events, use the master event ID to change all instances, or an instance ID to change only one occurrence
- `calendar_id` (string, optional, default: "primary") — Calendar ID containing the event
- `summary` (string, optional, default: "") — New event title. Leave empty to keep existing
- `start_time` (string, optional, default: "") — New start time in ISO 8601 format. Leave empty to keep existing
- `end_time` (string, optional, default: "") — New end time in ISO 8601 format. Leave empty to keep existing
- `description` (string, optional, default: "") — New event description. Leave empty to keep existing
- `location` (string, optional, default: "") — New event location. Leave empty to keep existing
- `timezone` (string, optional, default: "") — Timezone for the updated start/end times, e.g. 'America/New_York'. Leave empty to keep the event's existing timezone
- `status` (string, optional, default: "") — Event status: 'confirmed', 'tentative', or 'cancelled'. Set 'cancelled' on a recurring event instance ID to cancel only that occurrence without affecting the rest of the series
- `transparency` (string, optional, default: "") — Free/busy status: 'opaque' (shows as busy) or 'transparent' (shows as free). Leave empty to keep existing
- `reminder_minutes` (int, optional, default: -1) — Minutes before event for a popup reminder (0–40320). Set -1 to keep existing reminders
- `send_updates` (string, optional, default: "all") — Who receives update notifications: 'all', 'externalOnly', or 'none'
- `add_meet` (bool, optional, default: false) — Set True to add a Google Meet video conference link to this event. Has no effect if a Meet link already exists
- `guests_can_invite_others` (bool, optional) — Whether attendees can invite additional guests. Leave unset to keep existing value
- `guests_can_modify` (bool, optional) — Whether attendees can modify the event. Leave unset to keep existing value

Esquema de salida data:

{
  before: {
    id: string;
    summary: string | null;
    start: { date: string | null; dateTime: string | null; timeZone: string | null; };
    end: { date: string | null; dateTime: string | null; timeZone: string | null; };
    status: string | null;
    htmlLink: string | null;
    created: string | null;
    updated: string | null;
    description: string | null;
    location: string | null;
    colorId: string | null;
    creator: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    organizer: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    recurrence: string[] | null;
    recurringEventId: string | null;
    originalStartTime: { date: string | null; dateTime: string | null; timeZone: string | null; } | null;
    transparency: string | null;
    visibility: string | null;
    iCalUID: string | null;
    sequence: number | null;
    attendees: {
      email: string;
      id: string | null;
      displayName: string | null;
      organizer: boolean | null;
      self: boolean | null;
      resource: boolean | null;
      optional: boolean | null;
      responseStatus: string | null;
      comment: string | null;
      additionalGuests: number | null;
    }[] | null;
    attendeesOmitted: boolean | null;
    guestsCanInviteOthers: boolean | null;
    guestsCanModify: boolean | null;
    guestsCanSeeOtherGuests: boolean | null;
    hangoutLink: string | null;
    conferenceData: object | null;
    reminders: { useDefault: boolean; overrides: { method: string; minutes: number; }[] | null; } | null;
    eventType: string | null;
  };
  after: {
    id: string;
    summary: string | null;
    start: { date: string | null; dateTime: string | null; timeZone: string | null; };
    end: { date: string | null; dateTime: string | null; timeZone: string | null; };
    status: string | null;
    htmlLink: string | null;
    created: string | null;
    updated: string | null;
    description: string | null;
    location: string | null;
    colorId: string | null;
    creator: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    organizer: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    recurrence: string[] | null;
    recurringEventId: string | null;
    originalStartTime: { date: string | null; dateTime: string | null; timeZone: string | null; } | null;
    transparency: string | null;
    visibility: string | null;
    iCalUID: string | null;
    sequence: number | null;
    attendees: {
      email: string;
      id: string | null;
      displayName: string | null;
      organizer: boolean | null;
      self: boolean | null;
      resource: boolean | null;
      optional: boolean | null;
      responseStatus: string | null;
      comment: string | null;
      additionalGuests: number | null;
    }[] | null;
    attendeesOmitted: boolean | null;
    guestsCanInviteOthers: boolean | null;
    guestsCanModify: boolean | null;
    guestsCanSeeOtherGuests: boolean | null;
    hangoutLink: string | null;
    conferenceData: object | null;
    reminders: { useDefault: boolean; overrides: { method: string; minutes: number; }[] | null; } | null;
    eventType: string | null;
  };
}
add_attendees — Añade asistentes a un evento

Añade nuevos asistentes a un evento existente y les envía correos de invitación. Omite los correos que ya están en la lista de asistentes.

Entradas:

- `event_id` (string, required) — ID of the event to add attendees to
- `attendee_emails` (list[string], required) — Email addresses to add as required attendees
- `calendar_id` (string, optional, default: "primary") — Calendar ID containing the event
- `send_updates` (string, optional, default: "all") — Who receives invitation emails: 'all', 'externalOnly', or 'none'
- `optional_attendees` (list[string], optional, default: []) — Email addresses to add as optional attendees. These are invited but their attendance is not required

Esquema de salida data:

{
  before: {
    id: string;
    summary: string | null;
    start: { date: string | null; dateTime: string | null; timeZone: string | null; };
    end: { date: string | null; dateTime: string | null; timeZone: string | null; };
    status: string | null;
    htmlLink: string | null;
    created: string | null;
    updated: string | null;
    description: string | null;
    location: string | null;
    colorId: string | null;
    creator: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    organizer: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    recurrence: string[] | null;
    recurringEventId: string | null;
    originalStartTime: { date: string | null; dateTime: string | null; timeZone: string | null; } | null;
    transparency: string | null;
    visibility: string | null;
    iCalUID: string | null;
    sequence: number | null;
    attendees: {
      email: string;
      id: string | null;
      displayName: string | null;
      organizer: boolean | null;
      self: boolean | null;
      resource: boolean | null;
      optional: boolean | null;
      responseStatus: string | null;
      comment: string | null;
      additionalGuests: number | null;
    }[] | null;
    attendeesOmitted: boolean | null;
    guestsCanInviteOthers: boolean | null;
    guestsCanModify: boolean | null;
    guestsCanSeeOtherGuests: boolean | null;
    hangoutLink: string | null;
    conferenceData: object | null;
    reminders: { useDefault: boolean; overrides: { method: string; minutes: number; }[] | null; } | null;
    eventType: string | null;
  };
  after: {
    id: string;
    summary: string | null;
    start: { date: string | null; dateTime: string | null; timeZone: string | null; };
    end: { date: string | null; dateTime: string | null; timeZone: string | null; };
    status: string | null;
    htmlLink: string | null;
    created: string | null;
    updated: string | null;
    description: string | null;
    location: string | null;
    colorId: string | null;
    creator: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    organizer: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
    recurrence: string[] | null;
    recurringEventId: string | null;
    originalStartTime: { date: string | null; dateTime: string | null; timeZone: string | null; } | null;
    transparency: string | null;
    visibility: string | null;
    iCalUID: string | null;
    sequence: number | null;
    attendees: {
      email: string;
      id: string | null;
      displayName: string | null;
      organizer: boolean | null;
      self: boolean | null;
      resource: boolean | null;
      optional: boolean | null;
      responseStatus: string | null;
      comment: string | null;
      additionalGuests: number | null;
    }[] | null;
    attendeesOmitted: boolean | null;
    guestsCanInviteOthers: boolean | null;
    guestsCanModify: boolean | null;
    guestsCanSeeOtherGuests: boolean | null;
    hangoutLink: string | null;
    conferenceData: object | null;
    reminders: { useDefault: boolean; overrides: { method: string; minutes: number; }[] | null; } | null;
    eventType: string | null;
  };
}

Eventos — Eliminación

delete_event — Elimina permanentemente un evento

DESTRUCTIVO: REQUIERE CONFIRMACIÓN EXPLÍCITA DEL USUARIO ANTES DE LLAMARLO. Elimina permanentemente un evento de calendario. Esta acción es irreversible: el evento, su lista de asistentes, recordatorios y todos los datos asociados se eliminan de inmediato y no se pueden recuperar. Los asistentes recibirán correos de cancelación (controlados por send_updates). Para eventos recurrentes: eliminar el ID del evento maestro elimina toda la serie y todas sus instancias. Eliminar un ID de instancia específico elimina solo esa ocurrencia. NUNCA llames a esta herramienta de forma autónoma ni como parte de un flujo automatizado. DEBES detenerte, informar al usuario del título, fecha y hora del evento que se eliminará permanentemente y, para eventos recurrentes, aclarar si se elimina una ocurrencia o toda la serie, y esperar su confirmación escrita explícita antes de continuar.

Entradas:

- `event_id` (string, required) — ID of the event to delete
- `calendar_id` (string, optional, default: "primary") — Calendar ID containing the event
- `send_updates` (string, optional, default: "all") — Who receives cancellation emails: 'all' (recommended), 'externalOnly', or 'none'

Esquema de salida data:

{
  message: string;
}
move_event — Mueve un evento a otro calendario

DESTRUCTIVO: REQUIERE CONFIRMACIÓN EXPLÍCITA DEL USUARIO ANTES DE LLAMARLO. Mueve un evento predeterminado de un calendario a otro. Solo se pueden mover eventos de tipo 'default'; los eventos de cumpleaños, focusTime, fromGmail, outOfOffice y workingLocation no se pueden mover y devolverán un error. El evento se elimina del calendario de origen y se coloca en el calendario de destino; cualquier configuración específica del calendario, permisos de uso compartido o reglas de notificación del origen dejarán de aplicarse. Aunque técnicamente es reversible moviéndolo de vuelta, esto puede interrumpir a otros asistentes y la visibilidad del calendario compartido de formas difíciles de rastrear. NUNCA llames a esta herramienta de forma autónoma. DEBES informar al usuario qué evento se mueve, de qué calendario a cuál, y esperar su confirmación explícita.

Entradas:

- `event_id` (string, required) — ID of the event to move
- `source_calendar_id` (string, required) — ID of the calendar currently containing the event
- `destination_calendar_id` (string, required) — ID of the destination calendar

Esquema de salida data:

{
  id: string;
  summary: string | null;
  start: { date: string | null; dateTime: string | null; timeZone: string | null; };
  end: { date: string | null; dateTime: string | null; timeZone: string | null; };
  status: string | null;
  htmlLink: string | null;
  created: string | null;
  updated: string | null;
  description: string | null;
  location: string | null;
  colorId: string | null;
  creator: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
  organizer: { id: string | null; email: string | null; displayName: string | null; self: boolean | null; } | null;
  recurrence: string[] | null;
  recurringEventId: string | null;
  originalStartTime: { date: string | null; dateTime: string | null; timeZone: string | null; } | null;
  transparency: string | null;
  visibility: string | null;
  iCalUID: string | null;
  sequence: number | null;
  attendees: {
    email: string;
    id: string | null;
    displayName: string | null;
    organizer: boolean | null;
    self: boolean | null;
    resource: boolean | null;
    optional: boolean | null;
    responseStatus: string | null;
    comment: string | null;
    additionalGuests: number | null;
  }[] | null;
  attendeesOmitted: boolean | null;
  guestsCanInviteOthers: boolean | null;
  guestsCanModify: boolean | null;
  guestsCanSeeOtherGuests: boolean | null;
  hangoutLink: string | null;
  conferenceData: object | null;
  reminders: { useDefault: boolean; overrides: { method: string; minutes: number; }[] | null; } | null;
  eventType: string | null;
}

Calendarios

list_calendars — Lista todos los calendarios

Lista todos los calendarios a los que el usuario tiene acceso. Devuelve IDs de calendario, nombres, zonas horarias, colores y roles de acceso. Usa min_access_role para filtrar los calendarios en los que el usuario puede escribir.

Entradas:

- `min_access_role` (string, optional, default: "") — Minimum access role to filter by: 'freeBusyReader', 'reader', 'writer', or 'owner'. Empty returns all calendars
- `show_hidden` (bool, optional, default: false) — Include calendars hidden from the list view
- `max_results` (int, optional, default: 100) — Maximum number of calendars to return (1–250)
- `page_token` (string, optional, default: "") — Pagination token from a previous response's next_page_token to fetch the next page

Esquema de salida data:

{
  count: number;
  calendars: {
    id: string;
    summary: string;
    description: string | null;
    location: string | null;
    timeZone: string | null;
    accessRole: string | null;
    backgroundColor: string | null;
    foregroundColor: string | null;
    selected: boolean | null;
    primary: boolean | null;
    hidden: boolean | null;
  }[];
  next_page_token: string | null;
}
get_calendar — Obtiene un único calendario

Obtiene los detalles completos de un calendario específico, incluidos su nombre, descripción, zona horaria y configuración de color.

Entradas:

- `calendar_id` (string, optional, default: "primary") — Calendar ID. Use 'primary' for the user's main calendar

Esquema de salida data:

{
  id: string;
  summary: string;
  description: string | null;
  location: string | null;
  timeZone: string | null;
  accessRole: string | null;
  backgroundColor: string | null;
  foregroundColor: string | null;
  selected: boolean | null;
  primary: boolean | null;
  hidden: boolean | null;
}
create_calendar — Crea un nuevo calendario

Crea un nuevo calendario propiedad del usuario. Devuelve el calendario creado con su ID, que es necesario para todas las operaciones posteriores en ese calendario.

Entradas:

- `summary` (string, required) — Name of the new calendar
- `description` (string, optional, default: "") — Optional description for the calendar
- `timezone` (string, optional, default: "UTC") — IANA timezone name for the calendar, e.g. 'America/New_York'

Esquema de salida data:

{
  id: string;
  summary: string;
  description: string | null;
  location: string | null;
  timeZone: string | null;
  accessRole: string | null;
  backgroundColor: string | null;
  foregroundColor: string | null;
  selected: boolean | null;
  primary: boolean | null;
  hidden: boolean | null;
}
delete_calendar — Elimina permanentemente un calendario

DESTRUCTIVO: REQUIERE CONFIRMACIÓN EXPLÍCITA DEL USUARIO ANTES DE LLAMARLO. Elimina permanentemente un calendario completo y todos los eventos que contiene. Esta acción es irreversible: todos los eventos, series recurrentes e historial del calendario desaparecen de inmediato sin posibilidad de recuperarlos. NUNCA llames a esta herramienta de forma autónoma ni como parte de un flujo automatizado. DEBES detenerte, informar al usuario exactamente qué calendario se eliminará y que todos sus eventos se perderán permanentemente, y esperar su confirmación escrita explícita antes de continuar.

Entradas:

- `calendar_id` (string, required) — ID of the calendar to delete

Esquema de salida data:

{
  message: string;
}
clear_calendar — Elimina todos los eventos de un calendario

DESTRUCTIVO: REQUIERE CONFIRMACIÓN EXPLÍCITA DEL USUARIO ANTES DE LLAMARLO. Elimina permanentemente TODOS los eventos de un calendario sin eliminar el calendario en sí. Esta acción es irreversible: todos los eventos del calendario —pasados, presentes y futuros— se eliminan de inmediato sin posibilidad de recuperarlos. El calendario en sí permanece y se puede usar para nuevos eventos. Esta es la única forma de vaciar el calendario principal, que no se puede eliminar. NUNCA llames a esta herramienta de forma autónoma ni como parte de un flujo automatizado. DEBES detenerte, informar al usuario exactamente qué calendario se vaciará y que todos sus eventos se eliminarán permanentemente, y esperar su confirmación escrita explícita antes de continuar.

Entradas:

- `calendar_id` (string, required) — ID of the calendar to clear. Use 'primary' for the user's main calendar. WARNING: all events in this calendar will be permanently deleted

Esquema de salida data:

{
  message: string;
}

Disponibilidad (Free/Busy)

get_free_busy — Consulta bloques ocupados en todos los calendarios

Devuelve bloques de tiempo ocupado para uno o más calendarios dentro de un rango de tiempo. Úsalo para encontrar cuándo alguien está disponible o para programar sin conflictos. Proporciona time_min y time_max en formato ISO 8601 con zona horaria, p. ej. '2026-01-08T09:00:00Z'. Devuelve un mapa de ID de calendario → lista de bloques de tiempo ocupado. Tiempo libre = espacios entre los bloques ocupados dentro del rango solicitado.

Entradas:

- `time_min` (string, required) — Start of the query window in ISO 8601 format, e.g. '2026-01-08T09:00:00Z'
- `time_max` (string, required) — End of the query window in ISO 8601 format, e.g. '2026-01-08T17:00:00Z'
- `calendar_ids` (list[string], optional, default: []) — Calendar IDs to query. Defaults to ['primary'] if empty

Esquema de salida data:

{
  timeMin: string;
  timeMax: string;
  calendars: {
    [calendarId: string]: {
      busy: {
        start: string;
        end: string;
      }[];
      errors: object[] | null;
    };
  };
}

Referencia de Parámetros de la API

Envoltorio de Respuesta

Cada herramienta devuelve el mismo envoltorio de nivel superior. Solo data varía según la herramienta.

// Success
{
  success: true;
  statusCode: number;
  retriable: false;
  retry_after_seconds: null;
  error: null;
  data: { ... };   // schema shown per tool above
}

// Error
{
  success: false;
  statusCode: number;
  retriable: boolean;
  retry_after_seconds: number | null;
  error: {
    code: string;    // VALIDATION_ERROR | AUTH_ERROR | UPSTREAM_ERROR | SERVER_ERROR
    message: string;
    details: any;
  };
  data: null;
}
  • retriabletrue cuando es seguro reintentar (límite de velocidad, error de red, 503). false para errores de validación y autenticación.
  • retry_after_seconds — segundos de espera antes de reintentar; presente solo cuando retriable es true y el upstream especifica un retraso.
Formatos de Fecha y Hora

Todas las herramientas usan el formato ISO 8601 para valores de fecha y hora.

Eventos con hora:

YYYY-MM-DDTHH:MM:SS         local time (requires timezone param)
YYYY-MM-DDTHH:MM:SSZ        UTC
YYYY-MM-DDTHH:MM:SS±HH:MM   explicit offset

Eventos de día completo (usar con is_all_day=true):

YYYY-MM-DD    e.g. 2026-01-08

Para eventos de día completo, end_time es exclusivo — un evento de un solo día el 8 de enero necesita end_time='2026-01-09'.

Reglas de Recurrencia (RRULE)

create_recurring_event requiere una cadena RRULE RFC 5545 que comience con RRULE:.

RRULE:FREQ=DAILY;COUNT=5                     — 5 daily occurrences
RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR            — every Mon/Wed/Fri
RRULE:FREQ=MONTHLY;BYMONTHDAY=15            — 15th of each month
RRULE:FREQ=YEARLY                            — same date each year
RRULE:FREQ=WEEKLY;BYDAY=MO;UNTIL=20261231T000000Z  — until a date
ID de Calendario
  • primary — el calendario principal de Google del usuario (siempre válido)
  • Todos los demás calendarios usan un ID completo de list_calendars, p. ej. work@group.calendar.google.com

list_calendars devuelve id para cada calendario al que el usuario tiene acceso.

Paginación

list_events, search_events, list_event_instances y list_calendars admiten paginación mediante next_page_token.

Cuando data.next_page_token no es nulo en una respuesta, pásalo como page_token en la siguiente llamada con los mismos parámetros para recuperar la siguiente página.

Solución de Problemas

Encabezados Faltantes o Inválidos
  • Causa: token OAuth no proporcionado en los encabezados de la solicitud o formato incorrecto
  • Solución:
    1. Verifica que los encabezados Authorization: Bearer YOUR_TOKEN y X-Mewcp-Credential-Id: CREDENTIAL-ID estén presentes
    2. Comprueba que el token OAuth no haya expirado — vuelve a conectar en tu cuenta de MewCP si es necesario
Créditos Insuficientes
  • Causa: las llamadas a la API han superado tus límites de solicitudes
  • Solución:
    1. Revisa el uso de créditos en tu panel de Curious Layer
    2. Mejora a un plan de pago o agrega créditos para límites más altos
    3. Contacta al soporte para ajustes de créditos
Credencial No Conectada
  • Causa: no hay una credencial de Google Calendar vinculada a tu cuenta
  • Solución:
    1. Ve a Credenciales en tu panel de MewCP
    2. Conecta tu cuenta de Google (OAuth)
    3. Reintenta la solicitud con el encabezado X-Mewcp-Credential-Id correcto
Payload de Solicitud Malformado
  • Causa: el payload JSON es inválido o le faltan campos obligatorios
  • Solución:
    1. Valida la sintaxis JSON antes de enviar
    2. Asegúrate de que todos los parámetros obligatorios de la herramienta estén incluidos
    3. Verifica que los tipos de parámetros coincidan con los valores esperados (p. ej. time_min debe ser ISO 8601)
Servidor No Encontrado
  • Causa: nombre de servidor incorrecto en el endpoint de la API
  • Solución:
    1. Verifica el formato del endpoint: {server-name}/mcp/{tool-name}
    2. Usa el nombre de servidor correcto de la documentación
    3. Revisa los servidores disponibles en tu cuenta de Curious Layer
Error de la API de Google Calendar
  • Causa: la API de Google Calendar upstream devolvió un error
  • Solución:
    1. Revisa Google Workspace Status para problemas del servicio
    2. Verifica que tu cuenta de Google tenga los permisos de calendario necesarios
    3. Revisa el mensaje de error en la respuesta para obtener detalles específicos

Recursos