mcpField
M
mewcp-google-calendar

mewcp-google-calendar

本地服务
github.com/AStheTECH生产力26 周前更新

关于 mewcp-google-calendar

mewcp-google-calendar 是供 AI 工作流管理 Google Calendar 事件和日历的 MCP 服务。它涵盖事件搜索与安排、重复事件、参会者管理以及空闲忙碌查询。

主要功能

  1. 01列出、搜索和获取事件
  2. 02创建定时、全天和重复事件
  3. 03更新事件并管理参会者
  4. 04跨日历查询可用时间
  5. 05查询即将举行和当天的事件

适用场景

  1. 01通过 AI 工作流安排或改期会议
  2. 02按文本和日期范围查找事件
  3. 03协调参会邀请和重复会议
  4. 04在多个日历中查找空闲时段

MCP 相关

将 Google Calendar API 操作作为工具提供给 MCP 客户端,包括事件和日历管理、可用时间查询及事件创建。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"ammar-62-mewcp-google-calendar": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"docker.io/ammar62/mewcp-google-calendar:latest"
]
}
}
}
启动命令docker run -i --rm docker.io/ammar62/mewcp-google-calendar:latest

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
ocidocker.io/ammar62/mewcp-google-calendar:latest

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

更智能地安排日程 — 通过 AI 创建、搜索和管理 Google Calendar 事件。

一个 Model Context Protocol(MCP)服务,通过 Google Calendar API 创建、读取、更新和删除事件与日历。

概述

Google Calendar MCP 服务可直接从 AI 工作流全面管理日历:

  • 列出、搜索和获取事件,并可按时间范围、文本和重复规则进行丰富筛选
  • 创建单次、全天、快速和重复事件,并添加参会者、提醒和 Meet 链接
  • 更新事件并管理参会者,然后在单个响应中获取更改前后的状态
  • 查询多个日历的空闲/忙碌时段,以查找没有冲突的空闲时间

适用于:

  • 代表用户安排、重新安排和管理会议的 AI 助手
  • 读取日历状态以触发定时操作的工作流自动化
  • 协调空闲时间并在团队间发送邀请的 Agent

工具

事件 — 读取
list_events — 列出日历中的事件

列出日历在可选时间范围内的事件。按开始时间排序返回事件。重复事件会展开为单个实例。time_min/time_max 请使用 ISO 8601 格式:'YYYY-MM-DDTHH:MM:SSZ'(例如 '2026-01-08T00:00:00Z')。如果未指定 time_min,则默认返回从现在起的事件。

输入:

- `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

输出 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 — 按 ID 获取单个事件

获取特定事件的完整详情,包括参会者、RSVP 状态、重复规则、提醒和会议详情。

输入:

- `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

输出 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 — 按文本搜索事件

按文本搜索事件,范围涵盖标题、说明和地点。可通过 time_min/time_max 将搜索限制在某个时间范围内(ISO 8601 格式,例如 '2026-01-08T00:00:00Z')。如果未指定时间范围,搜索将涵盖所有历史记录 — 对于大型日历,请始终指定时间范围。

输入:

- `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

输出 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 — 获取未来 N 天内的事件

获取从现在起至未来 N 天内开始的事件。按开始时间排序返回事件。重复事件会展开为单个实例。

输入:

- `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)

输出 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 — 获取今天的所有事件

获取指定时区中今天安排的所有事件。传入用户的本地时区以获取正确的日期(例如 'America/New_York')。默认使用 UTC。

输入:

- `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

输出 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 — 列出重复事件的实例

按主事件 ID 列出重复事件的所有单独实例。使用此工具查看重复系列中的每次发生 — 请先使用 get_event 或 list_events 查找主事件 ID。实例包含 recurringEventId(主事件 ID)和 originalStartTime(根据 RRULE 设定的计划时间;如果实例已重新安排,该时间会与 start 不同)。可按时间范围筛选,仅查看即将发生或已经过去的实例。

输入:

- `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

输出 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;
}
### 事件 — 写入
create_event — 创建新的日历事件

创建新的日历事件,并可选择邀请参会者。定时事件请使用 ISO 8601 日期时间格式:'2026-01-08T14:30:00',并指定时区。全天事件请设置 is_all_day=True,并使用仅包含日期的格式:'2026-01-08'。全天事件的 end_time 不包含在内,因此 1 月 8 日的单日事件需要设置 end_time='2026-01-09'。返回创建的事件及其 ID。

输入:

- `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

输出 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 — 根据自然语言创建事件

根据自然语言文本描述创建事件。Google Calendar 会解析文本,提取标题、日期、时间和重复规则。示例:'明天中午与 Sarah 共进午餐'、'每周一上午 9 点团队站会'。返回创建的事件。对于包含参会者或自定义字段的复杂事件,请改用 create_event。

输入:

- `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'

输出 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 — 使用 RRULE 创建重复事件

使用 RRULE 重复模式创建重复日历事件。recurrence_rule 必须以 'RRULE:' 开头,后接 RFC 5545 参数。示例:'RRULE:FREQ=DAILY;COUNT=5'、'RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR'、'RRULE:FREQ=MONTHLY;BYMONTHDAY=15'、'RRULE:FREQ=YEARLY'。返回主重复事件 — Google Calendar 会展开各个实例。

输入:

- `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

输出 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 — 更新现有事件

更新现有日历事件。只会更改你提供的字段 — 将字段留空即可保留其当前值。工具会先获取当前事件,应用更改,然后保存。时间请使用 ISO 8601 格式:'YYYY-MM-DDTHH:MM:SS'。对于重复事件:传入主重复事件 ID 可更改所有实例,传入特定实例 ID 则只更改该次事件。警告:请勿逐个更新单独实例来更改整个系列 — 应改为更新主事件。单独修改各个实例会创建例外项,使日历变得杂乱,并触发过多通知。若要取消某个实例而不影响系列中的其他事件,请设置 status='cancelled'。

输入:

- `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

输出 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 — 向事件添加参会者

向现有事件添加新参会者,并向他们发送邀请邮件。已在参会者名单中的邮箱将被跳过。

输入:

- `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

输出 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;
  };
}
### 事件 — 删除
delete_event — 永久删除事件

破坏性操作 — 调用前必须获得用户的明确确认。永久删除日历事件。此操作不可逆:事件、参会者列表、提醒和所有关联数据都会立即移除,且无法恢复。参会者将收到取消邮件(由 send_updates 控制)。对于重复事件:删除主事件 ID 会移除整个系列及其所有实例。删除特定实例 ID 只会移除该次事件。绝不要自主调用此工具,也不要将其用于自动化流程。你必须暂停操作,告知用户即将永久删除的事件标题、日期和时间;对于重复事件,还要说明删除的是单次事件还是整个系列,并等待用户明确书面确认后再继续。

输入:

- `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'

输出 data 架构:

{
  message: string;
}
move_event — 将事件移至其他日历

破坏性操作 — 调用前必须获得用户的明确确认。将默认事件从一个日历移至另一个日历。只有类型为 'default' 的事件可以移动 — birthday、focusTime、fromGmail、outOfOffice 和 workingLocation 事件无法移动,调用时会返回错误。事件会从源日历移除并放入目标日历 — 源日历的任何日历专属设置、共享权限或通知规则都不再适用。虽然从技术上讲可以通过移回原处来撤销,但这可能会影响其他参会者和共享日历的可见性,而且问题很难追查。绝不要自主调用此工具。你必须告知用户要移动哪个事件,以及从哪个日历移至哪个日历,并等待用户明确确认。

输入:

- `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

输出 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;
}
### 日历
list_calendars — 列出所有日历

列出用户有权访问的所有日历。返回日历 ID、名称、时区、颜色和访问角色。使用 min_access_role 筛选用户可写入的日历。

输入:

- `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

输出 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 — 获取单个日历

获取特定日历的完整详情,包括名称、说明、时区和颜色设置。

输入:

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

输出 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 — 创建新日历

创建一个归用户所有的新日历。返回已创建日历及其 ID,后续对该日历进行的所有操作都需要此 ID。

输入:

- `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'

输出 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 — 永久删除日历

破坏性操作 — 调用前必须获得用户的明确确认。永久删除整个日历及其中的所有事件。此操作不可逆:日历中的所有事件、重复系列和历史记录都会立即消失,且无法恢复。绝不要自主调用此工具,也不要将其作为自动化流程的一部分。你必须停止操作,明确告知用户将删除哪个日历以及其中的所有事件都将永久丢失,并等待用户以书面形式明确确认后再继续。

输入:

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

输出 data 架构:

{
  message: string;
}
clear_calendar — 删除日历中的所有事件

破坏性操作 — 调用前必须获得用户的明确确认。永久删除日历中的所有事件,但不会删除日历本身。此操作不可逆:日历中的每个事件——过去、现在和未来的事件——都会立即被移除,且无法恢复。日历本身会保留,可用于创建新事件。这是清空主日历的唯一方式,因为主日历无法删除。绝不要自主调用此工具,也不要将其作为自动化流程的一部分。你必须停止操作,明确告知用户将清空哪个日历以及其中的每个事件都将被永久删除,并等待用户以书面形式明确确认后再继续。

输入:

- `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

输出 data 架构:

{
  message: string;
}
空闲/忙碌
get_free_busy — 查询各日历中的忙碌时段

返回一个或多个日历在指定时间范围内的忙碌时段。可用于查找某人的空闲时间或安排日程以避免冲突。请以 ISO 8601 格式(包含时区)提供 time_min 和 time_max,例如 '2026-01-08T09:00:00Z'。返回一个映射:日历 ID → 忙碌时段列表。空闲时间 = 请求时间范围内各忙碌时段之间的间隔。

输入:

- `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

输出 data 架构:

{
  timeMin: string;
  timeMax: string;
  calendars: {
    [calendarId: string]: {
      busy: {
        start: string;
        end: string;
      }[];
      errors: object[] | null;
    };
  };
}
## API 参数参考
响应封套

每个工具都会返回相同的顶层封套。只有 data 会因工具而异。

// 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;
}
  • retriable — 当可以安全重试时(速率限制、网络错误、503)为 true。对于验证和身份验证错误,则为 false。
  • retry_after_seconds — 重试前需要等待的秒数;仅当 retriable 为 true 且上游指定了延迟时间时才会出现。
日期和时间格式

所有工具的日期和时间值均使用 ISO 8601 格式。

定时事件:

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

全天事件(与 is_all_day=true 搭配使用):

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

对于全天事件,end_time 不包含在内——1 月 8 日的单日事件需要设置 end_time='2026-01-09'。

重复规则(RRULE)

create_recurring_event 要求提供以 RRULE: 开头的 RFC 5545 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
  • primary — 用户的主 Google Calendar(日历)(始终有效)
  • 其他所有日历均使用 list_calendars 返回的完整 ID,例如 [email protected]

list_calendars 会返回用户有权访问的每个日历的 id。

分页

list_events、search_events、list_event_instances 和 list_calendars 支持通过 next_page_token 分页。

当响应中的 data.next_page_token 不为 null 时,在下一次使用相同参数的调用中将其作为 page_token 传入,以获取下一页。

## 故障排除
缺少或无效的请求头
  • 原因: 请求头中未提供 OAuth 令牌,或令牌格式不正确
  • 解决方案:
    1. 确认请求中包含 Authorization: Bearer YOUR_TOKEN 和 X-Mewcp-Credential-Id: CREDENTIAL-ID 请求头
    2. 检查 OAuth 令牌是否已过期 — 如有需要,请在 MewCP 账户中重新连接
积分不足
  • 原因: API 调用已超过请求限额
  • 解决方案:
    1. 在 Curious Layer 控制面板中查看积分使用情况
    2. 升级到付费套餐或添加积分以提高限额
    3. 联系支持团队调整积分
凭据未连接
  • 原因: 账户未关联 Google Calendar 凭据
  • 解决方案:
    1. 前往 MewCP 控制面板中的 Credentials
    2. 连接你的 Google 账户(OAuth)
    3. 使用正确的 X-Mewcp-Credential-Id 请求头重试请求
请求负载格式错误
  • 原因: JSON 负载无效或缺少必填字段
  • 解决方案:
    1. 发送前验证 JSON 语法
    2. 确保包含所有必填工具参数
    3. 检查参数类型是否符合预期(例如,time_min 必须采用 ISO 8601 格式)
找不到服务
  • 原因: API 端点中的服务名称不正确
  • 解决方案:
    1. 验证端点格式:{server-name}/mcp/{tool-name}
    2. 使用文档中的正确服务名称
    3. 在 Curious Layer 账户中查看可用服务
Google Calendar API 错误
  • 原因: 上游 Google Calendar API 返回了错误
  • 解决方案:
    1. 查看 Google Workspace 状态,了解服务是否存在问题
    2. 确认你的 Google 账户拥有所需的日历权限
    3. 查看响应中的错误消息,了解具体详情

资源

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。