mcpField
G
Google Calendar MCP Server (Python)

Google Calendar MCP Server (Python)

本地服务
github.com/deciduus生产力274 周前更新

关于 Google Calendar MCP Server (Python)

Google Calendar MCP Server 是一个基于 Python 的 MCP 服务,让 LLM 客户端可以读写 Google Calendar 并通过自然语言完成日程操作。它提供 23 个工具,并内置了解工作时间的日程规划功能。认证采用 Google OAuth 2.0 桌面应用流程,令牌本地缓存并自动刷新。

主要功能

  1. 0123 个带结构化输出的日历读写工具
  2. 02多账号登录,可按调用指定账号
  3. 03空闲时段查找与专注时间预订
  4. 04跨多个账号的重复预订冲突检测
  5. 05按工作时间与指标统计的时间审计
  6. 06HTTP 传输模式,默认无认证层

适用场景

  1. 01让 LLM 查询日程并创建或修改事件
  2. 02为深度工作预留一段专注时间
  3. 03检查工作与个人日历之间是否存在重复预订
  4. 04统计一段时间内会议占用的时长

MCP 相关

该项目是一个 MCP 服务,向 MCP 客户端暴露日历与日程规划相关工具,支持 stdio 和 streamable HTTP 两种传输方式。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"calendar": {
"command": "uvx",
"args": [
"calendar-mcp-server"
],
"env": {
"GOOGLE_CLIENT_ID": "<GOOGLE_CLIENT_ID>",
"GOOGLE_CLIENT_SECRET": "<GOOGLE_CLIENT_SECRET>",
"TOKEN_FILE_PATH": "<TOKEN_FILE_PATH>"
}
}
}
}
启动命令uvx calendar-mcp-server
需要配置的环境变量
GOOGLE_CLIENT_IDOAuth 2.0 client ID for a Google Cloud project with the Google Calendar API enabled.
GOOGLE_CLIENT_SECRET密钥OAuth 2.0 client secret matching GOOGLE_CLIENT_ID.
TOKEN_FILE_PATH密钥Path to the saved OAuth token file written by 'calendar-mcp auth'.

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

安装包
pypicalendar-mcp-server1.0.1

工具

15

收录的工具列表 · 更新于 3 周前

参数类型必填说明
min_access_roleany否

详细介绍

calendar-mcp

一个 MCP 服务,让大模型客户端可以读写你的 Google Calendar。它以单个进程运行——默认使用 stdio,可选 streamable HTTP——并暴露 23 个带结构化输出的工具:列出和搜索日历与事件,创建、更新、移动、回复邀请(RSVP)和删除事件,空闲/忙碌查询,忙碌度分析,重复事件投影,以及查找共同空闲时段并预订。除此之外,它还有一个了解你工作时间的日程安排大脑:查找并预订专注时间,一次性检测多个账号之间的双重预订,为会议提议更好的时间,并审计你的一周实际花在了哪里。身份验证使用 Google OAuth 2.0(桌面应用流程);令牌会按账号缓存在本地,并自动刷新。

一个日历任务,端到端

合成示例,由离线测试支持;没有真实日历数据或实时预订。 假设周四的工作时间为 09:00–17:00 UTC,11:00–12:00 有一个会议, 没有午餐或缓冲时间,最短专注块为 60 分钟。

“在 2026 年 1 月 1 日找出六小时的专注时间。先给我看这些时间块。”

MCP 客户端可以调用:

{
  "tool": "block_focus_time",
  "arguments": {
    "time_min": "2026-01-01T00:00:00Z",
    "time_max": "2026-01-02T00:00:00Z",
    "hours_needed": 6,
    "dry_run": true
  }
}

预览会选择 09:00–10:00 和 12:00–17:00:共六小时,最后一个 选中的时间块被裁剪到剩余的一小时。两个事件都有 created: false。 在用户批准这些时间后,客户端可以用 dry_run: false 调用; 在创建事件之前会再次读取可用性。预览不会预留时段。

设计决策:未知可用性不等于空闲时间。 如果被检查的日历 返回访问错误、从响应中消失,或有无法读取的忙碌区间, 专注时间搜索和预订会在写入任何内容之前返回错误。 同样的检查也保护共同日程安排和重新安排建议/应用。 例如,对 [email protected] 的 notFound 响应会变成:

Availability is unknown: [email protected]: notFound. No scheduling changes were made.
Restore calendar access or retry the query.

无需 Google 凭据即可复现预览和安全回归 (在开发安装之后):

pytest -q tests/test_scheduling.py -k 'focus_time_dry_run or focus_refuses_unknown'

该回归测试验证:在预览和预订两种模式下,部分、缺失和出错的 可用性都绝不会调用 create_event。成功的空忙碌列表仍然 意味着真正的空闲时间。可用性检查和写入是分开的 Google API 调用, 因此另一个客户端仍可能在这两者之间预订一个冲突事件。

快速开始

1. 创建 Google OAuth 凭据。 在 Google Cloud 控制台中,启用 Google Calendar API,然后创建一个类型为 桌面应用 的 OAuth 客户端 ID。复制客户端 ID 和密钥。(详情见 Google Cloud 设置。)

2. 将它们设置到你的环境中,或设置到你运行所在目录的 .env 文件中(见 example.env):

GOOGLE_CLIENT_ID='...'
GOOGLE_CLIENT_SECRET='...'

3. 登录一次,然后把该服务添加到你的客户端:

uvx calendar-mcp-server auth

这会打开浏览器并在配置目录中保存一个令牌(见账号);如果你已有 .gcp-saved-tokens.json 或设置了 TOKEN_FILE_PATH,则改用该文件。用 calendar-mcp check 验证。用 calendar-mcp auth --account work 添加更多 Google 账号。之后该服务以非交互方式运行——除非你设置 CALENDAR_MCP_ALLOW_BROWSER_AUTH=1,否则它绝不会自行打开浏览器。

PyPI 发行包是 calendar-mcp-server。它会安装两个相同的控制台脚本,calendar-mcp 和 calendar-mcp-server,因此 uvx calendar-mcp-server 和本地的 calendar-mcp 是同一个命令。

客户端配置

Claude Code

claude mcp add calendar \
  --env GOOGLE_CLIENT_ID=... \
  --env GOOGLE_CLIENT_SECRET=... \
  -- uvx calendar-mcp-server

Claude Desktop —— claude_desktop_config.json:

{
  "mcpServers": {
    "calendar": {
      "command": "uvx",
      "args": ["calendar-mcp-server"],
      "env": {
        "GOOGLE_CLIENT_ID": "...",
        "GOOGLE_CLIENT_SECRET": "...",
        "TOKEN_FILE_PATH": "/absolute/path/to/.gcp-saved-tokens.json"
      }
    }
  }
}

Cursor —— .cursor/mcp.json(项目)或 ~/.cursor/mcp.json(全局):与上面相同的 mcpServers 块。

任何其他客户端,只要它使用标准的 mcpServers JSON,都采用相同的条目。TOKEN_FILE_PATH 现在是可选的,因为令牌默认存放在操作系统配置目录中,这不依赖于客户端选择的工作目录——但如果你确实设置了它,请使用绝对路径。

远程 / HTTP 模式

calendar-mcp --transport http --host 127.0.0.1 --port 8000

此时 MCP 端点为 http://127.0.0.1:8000/mcp(用 --path 修改路径)。

HTTP 传输上目前还没有认证层。 任何能访问该端点的人都能完全访问已保存令牌所属的日历。请将其绑定到回环地址,或仅将其暴露在会进行认证的可信反向代理之后,或私有网络(如 tailnet)中。不要将其放在公网接口上。

工具

只读工具永远不会更改任何内容。“写入”工具会创建或修改事件; delete_event 是唯一会销毁数据的工具。

日历与事件

工具描述
list_calendars读取列出用户可见的日历,包含 ID 和时区。
find_events读取在日历中搜索事件,并将重复系列展开为实例。
check_attendee_status读取报告谁接受、拒绝或尚未回复邀请。
query_free_busy读取一个或多个日历的忙碌时间段,不含事件详情。
analyze_busyness读取某时间段内每日事件数量和总日程分钟数。
project_recurring_events读取根据重复规则计算未来的发生时间。
create_calendar写入创建新的次级日历。
create_event写入创建具有明确开始/结束时间和可选参与者的事件。
quick_add_event写入根据自然语言短语创建事件,由 Google 解析。
update_event写入更改事件字段;省略的字段保持不变。
move_event写入重新安排事件时间,和/或将其移动到另一个日历。
add_attendee写入邀请一人或多人参加现有事件。
respond_to_event写入设置自己的 RSVP(accepted/declined/tentative/needsAction)。
schedule_mutual写入找到所有人都空闲的第一个时间段,然后预订。
delete_event销毁永久删除事件。在支持时,通过 elicitation 请求客户端确认。

调度大脑 — 这些工具会读取你保存的偏好设置(工作时间、午餐、缓冲时间、最短专注时段)。

工具描述
find_focus_time读取某时间窗口内可用于深度工作的不间断时间段,按从长到短排序。
detect_conflicts读取跨所有已登录账户,找出重复预订和过于紧凑的衔接。
time_audit读取时间都去哪儿了:会议时长,按规模、领域、重复和人员分类。
suggest_reschedule写入 (可选启用)为现有会议推荐更合适的备选时间,按优先级排序。仅建议,除非 apply: true。
block_focus_time写入将最佳空闲时间段预订为专注时间。使用 dry_run: true 预览。

本地配置 — 不调用 Google,没有 account 参数。

工具描述
list_accounts读取你已登录的账户,以及哪个是默认账户。
get_preferences读取工作时间、午餐、缓冲时间、最短专注时段、专注日历。
set_preferences写入更新并保存这些偏好设置。仅限本地文件。

每个日历工具都接受一个可选的末尾 account 参数(detect_conflicts 接受 accounts,是一个列表,因为同时检查多个账户正是其目的)。所有时间 都是 ISO 8601 字符串——不带时区的时间戳会按目标日历自身的时区进行解释。

调度大脑

这五个调度工具共享同一个理念:你的日历并不等同于你的空闲时间。它们从你的工作时间出发,减去午餐时间,减去已有安排,再减去你希望在会议前后留出的缓冲时间——然后对剩余时间进行推理。

用于测试它们的提示词:

  • “帮我找出下周六小时的专注时间并预订下来——先把时间段给我看看。”
  • “这周我的工作日历和个人日历之间有重复预订吗?”
  • “我周四的安排一个接一个。给设计评审建议更好的时间。”
  • “上个月我的时间都花在哪了?我都在和谁相处?”
  • “我需要在周五之前有一个 90 分钟的深度工作时段。有吗?”

find_focus_time 报告现有的空闲时间;block_focus_time 通过创建事件来守护它(忙碌、关闭提醒、不通知任何人),并裁剪最后一个时间段,使其正好预订你要求的时长,而不是整个下午。detect_conflicts 将真正的重叠与仅仅打破你缓冲时间的紧凑过渡区分开来,并忽略你已拒绝的事件、标记为空闲的事件,以及(默认情况下)全天事项。suggest_reschedule 保持会议时长不变,按参会者冲突最少对候选时间段排序,并优先选择事件当前所在的日期;除非你传入 apply: true,否则不会移动任何内容。

时间审计

time_audit 一次性回答“我这一周有多少时间花在会议上?”,可按 day 或 week 分组:

2026-08-01 .. 2026-09-01, Europe/Berlin, grouped by week
  Meetings:         41.5 h across 63 meetings
  Working hours:    152.0 h available (lunch removed)
  In working hours: 38.0 h -> 25% of the week
  Busiest week:     2026-W34, 14.0 h
  Heaviest day:     2026-08-20, 6.5 h
  By size:          1:1 18.0 h | small 15.5 h | large 8.0 h
  By recurrence:    recurring 26.0 h | one-off 15.5 h
  Top people:       [email protected] 9.0 h | [email protected] 7.5 h

已拒绝的会议、标记为空闲的事件和全天事项默认被排除;include_declined 和 include_all_day 可将它们重新纳入。

安全
  • delete_event 是唯一的破坏性工具。 当客户端支持时,它会通过 MCP elicitation 请求客户端确认;不支持时则正常继续。
  • block_focus_time 接受 dry_run。 用 dry_run: true 运行它,即可在写入任何内容之前查看它将预订的具体时间段。目标日历始终包含在可用性检查中。
  • 调度在可用性未知时采用失败关闭策略。 专注时间搜索/预订、两条互相调度路径,以及重新安排建议/应用,都要求每个被检查的日历具有可读取的可用性。错误会在写入之前返回,而不是在预订之后作为警告。请恢复访问权限或重试后再调度。默认的专注日历发现也会拒绝不完整、分页的日历列表;在这种情况下,请通过 calendar_ids / check_calendar_ids 提供明确的完整列表。
  • suggest_reschedule 默认不移动任何内容。 apply 为 false,必须在用户同意某个时间后显式设置。
  • 其他所有写入操作都是增量式的——创建或编辑事件——并且 update_event 会保留你省略的字段不变。
  • list_accounts、get_preferences 和 set_preferences 从不接触 Google。 它们读写配置目录中的本地文件。

账户

你可以登录多个 Google 账户,并在每次调用时从中选择。

calendar-mcp auth                    # the default account
calendar-mcp auth --account work     # a second, named account
calendar-mcp accounts                # list them, with token paths and sign-in state

每个日历工具都接受一个可选的 account 参数,用于指定其中一个账户(“我明天的工作日历上有什么?”)。省略该参数时,服务将使用默认值:如果设置了 CALENDAR_MCP_DEFAULT_ACCOUNT 则使用它,否则使用名为 default 的账户,否则使用你唯一登录的账户。list_accounts 返回与 CLI 打印相同的列表,因此模型可以自行发现这些名称。

账户名称必须匹配 [A-Za-z0-9][A-Za-z0-9_-]{0,63}。

文件存放位置。 令牌和偏好设置存储在操作系统用户配置目录中 —— Windows 上为 %LOCALAPPDATA%\calendar-mcp,Linux 上为 ~/.config/calendar-mcp,macOS 上为 ~/Library/Application Support/calendar-mcp —— 每个账户在 accounts/ 下有一个令牌文件。可通过 CALENDAR_MCP_CONFIG_DIR 覆盖整个目录。

向后兼容。 TOKEN_FILE_PATH 仍然有效,现在表示默认账户的令牌。如果设置了它,或者工作目录中存在 .gcp-saved-tokens.json,则该文件将用于 default 账户,其他文件不会移动。具名账户始终位于配置目录中。

偏好设置

服务会记住你希望一周如何安排,这样调度工具就无需猜测。使用 get_preferences 读取它们,使用 set_preferences 修改它们(“我从 8 点开始,会议之间要留 15 分钟”)。偏好设置是全局的 —— 它们描述的是你,而不是某个账户 —— 并以 preferences.json 的形式存储在配置目录中。

字段默认值含义
timezone未设置工作时间所用的 IANA 时区,例如 Europe/Berlin。
working_hours周一至周五 09:00–17:00按星期几(mon…sun),一个 ["HH:MM", "HH:MM"] 时间段的列表。
buffer_minutes0提议时间时,会议前后要留出的间隔。
min_focus_block_minutes60仍然算作可用专注时间的最短空闲时段。
lunch未设置从工作时间内划出的每日休息时间。
focus_calendar_idprimary预订专注时间块的日历。
{
  "timezone": "Europe/Berlin",
  "working_hours": {
    "mon": [["09:00", "12:00"], ["13:00", "18:00"]],
    "tue": [["09:00", "17:00"]],
    "wed": [["09:00", "17:00"]],
    "thu": [["09:00", "17:00"]],
    "fri": [["09:00", "15:00"]],
    "sat": [],
    "sun": []
  },
  "buffer_minutes": 15,
  "min_focus_block_minutes": 90,
  "lunch": ["12:30", "13:15"],
  "focus_calendar_id": "primary"
}

set_preferences 采用合并方式:只有你传入的参数会改变,合并后的结果在写入前会经过验证,因此被拒绝的更改不会影响已保存的文件。唯一的例外是 working_hours,它是整个日程的替换 —— 你在字典中省略的星期几将变为非工作日。传入 clear_lunch: true 可移除午休时间。

配置

变量默认值用途
GOOGLE_CLIENT_ID—OAuth 客户端 ID(必填)。
GOOGLE_CLIENT_SECRET—OAuth 客户端密钥(必填)。
TOKEN_FILE_PATH.gcp-saved-tokens.json默认账户的 OAuth 令牌缓存位置。
CALENDAR_MCP_CONFIG_DIR操作系统用户配置目录存放各账户令牌(accounts/)和 preferences.json 的目录。
CALENDAR_MCP_DEFAULT_ACCOUNTdefault当工具的 account 参数被省略时使用的账户。
CALENDAR_SCOPEShttps://www.googleapis.com/auth/calendar请求的范围。只读请使用 .../auth/calendar.readonly。
OAUTH_CALLBACK_PORT8080calendar-mcp auth 期间 OAuth 回调的本地端口。
CALENDAR_MCP_ALLOW_BROWSER_AUTH未设置设为 1 以允许服务本身在无令牌时打开浏览器。默认关闭,这样 stdio 服务永远不会挂起。
CALENDAR_MCP_LOG_FILE未设置将 stderr 日志镜像到此文件。
CALENDAR_MCP_LOG_LEVELINFODEBUG/INFO/WARNING/ERROR/CRITICAL。覆盖 --log-level。
HOST127.0.0.1HTTP 模式下 --host 的默认值。
PORT8000HTTP 模式下 --port 的默认值。

工作目录中的 .env 文件会在启动时加载。日志绝不会输出到 stdout —— 在 stdio 模式下,stdout 是 MCP 协议通道。

命令
calendar-mcp [--transport {stdio,http}] [--host H] [--port P] [--path /mcp] [--log-level L]
calendar-mcp serve ...     # explicit form of the default
calendar-mcp auth [--account NAME] [--no-browser]
calendar-mcp accounts      # list known accounts; exit 1 if none is signed in
calendar-mcp check [--account NAME]   # token status + calendar list; exit 1 if no valid token
calendar-mcp --version

python -m calendar_mcp 接受相同的参数。

Google Cloud 设置

  1. 创建或选择一个项目,并启用 Google Calendar API。
  2. APIs & Services → Credentials → Create credentials → OAuth client ID → Application type: Desktop app。 复制 client ID 和 secret。没有需要保留的 JSON 下载文件。
  3. Desktop app 客户端没有 "Authorized redirect URIs" 字段——Google 允许此类客户端在任意端口使用 http://localhost,这正是 OAUTH_CALLBACK_PORT 上的本地回调所使用的。此处无需配置任何内容。
  4. 在 OAuth consent screen 中:User Type 选择 External,填写应用名称和联系人邮箱,添加 https://www.googleapis.com/auth/calendar 权限范围,并将你自己的 Google 账号添加为测试用户。若缺少最后一步,登录将被拒绝。

开发

git clone https://github.com/deciduus/calendar-mcp
cd calendar-mcp
uv venv
uv pip install -e ".[dev]"
pytest

目录结构:calendar_mcp/server.py(MCPServer、共享辅助函数和凭据提供程序)、tools/(每个工具领域一个模块——即工具函数本身)、calendar_actions.py(Google API 调用)、analysis.py、timeutil.py(纯区间计算)、accounts.py(多账号 token 路径)、preferences.py(已保存的日程)、models.py(pydantic 输入/输出模型)、auth.py(OAuth)、cli.py(calendar-mcp 命令)。scripts/smoke_stdio.py 会启动一个真实的 stdio 服务,并检查握手和工具列表。

从 1.0 升级

不会有任何破坏。全部 15 个原有工具保留其名称和现有参数;每个工具只是新增了一个可选的末尾 account 参数。你现有的 TOKEN_FILE_PATH 仍然有效,现在它指定的是默认账号的 token。调度安全性:不可用、缺失或格式错误的忙/闲数据现在会导致专注时间搜索、预览、互相调度和重新调度返回错误。在可用性信息不完整时,不会自动进行任何调度变更。

新增内容:多账号、已保存的调度偏好,以及八个新工具(find_focus_time、block_focus_time、detect_conflicts、suggest_reschedule、time_audit、list_accounts、get_preferences、set_preferences)。

从 0.x 升级

  • 包和命令已重命名。 发行包现在名为 calendar-mcp-server,并安装 calendar-mcp(以及一个完全相同的 calendar-mcp-server 别名)。请将你的客户端指向 uvx calendar-mcp-server,而不是 python /path/to/run_server.py。
  • run_server.py 仍然可用——它现在只是 CLI 之上的一层薄垫片——但已弃用,并将在未来版本中移除。
  • FastAPI/uvicorn HTTP API 已移除。 不再有 REST 端点、没有 /health,也没有单独的 stdio 桥接进程;该服务是基于 MCP SDK 的单一进程。如果你需要 HTTP,现在是在 /mcp 上的 MCP streamable HTTP。
  • 认证不再隐式发生。 运行一次 calendar-mcp auth;除非设置 CALENDAR_MCP_ALLOW_BROWSER_AUTH=1,否则服务不会打开浏览器。
  • 工具名称未变,因此现有提示词仍然可用。结果现在是结构化输出,而不是塞进文本里的 JSON。
  • 三个新工具: move_event、respond_to_event 和 project_recurring_events(最后一个此前仅作为内部逻辑存在)。
  • 已移除的环境变量:RELOAD、MCP_API_HOST。HOST/PORT 现在适用于 MCP HTTP 传输。

许可证

本项目采用双许可模式,以同时支持开源协作与可持续发展:

  1. GNU Affero 通用公共许可证 v3.0(AGPL-3.0):

    • 在 AGPLv3 许可证条款下,本软件可自由使用、修改和分发。
    • 关键条件包括:衍生作品(包括通过网络使用的修改版本)也必须以 AGPLv3 许可,并公开其源代码。
    • 该许可证适用于开源项目或能够满足 AGPLv3 合规要求的内部使用场景。
    • 完整文本请参见 LICENSE 文件。
  2. 商业许可证:

    • 如果 AGPLv3 的条款不适合您的具体使用场景(例如,在不遵守 AGPLv3 源代码共享要求的情况下,将本软件集成到专有的闭源商业产品或服务中),可另行获取商业许可证。
    • 有关商业许可方案的咨询,请联系 [email protected]。

使用、修改或分发本软件,即表示您同意接受 AGPLv3 或另行协商的商业许可证条款的约束。

mcp-name: io.github.deciduus/calendar-mcp

评论

支持 Markdown

第一次接触 MCP?

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

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