Skip to main content
Glama
REVREBEL

Google Calendar MCP OAuth Proxy

by REVREBEL

Google Calendar MCP OAuth Proxy

此 Worker 充当 MCP 客户端(例如 Codex)与 Google 官方 Calendar MCP 之间的 OAuth 边界。

Codex / MCP client
        |
        | OAuth to this Worker
        v
Cloudflare OAuth Provider
        |
        | Google OAuth (client ID + client secret)
        v
Google OAuth
        |
        | Google access token
        v
Google Calendar MCP
https://calendarmcp.googleapis.com/mcp/v1

客户端永远不会接触 Google 的 OAuth 客户端密钥。Google 访问令牌和刷新令牌存储在加密的 OAuth 授权属性中,这些属性由 Cloudflare OAuth 提供方管理。受保护的 /mcp 处理程序会在将 MCP 流量转发到上游之前,使用用户的 Google 访问令牌替换客户端本地的 bearer 令牌。

Google 作用域

wrangler.jsonc 在 GOOGLE_OAUTH_SCOPES 中定义了 Google Calendar 作用域:

https://www.googleapis.com/auth/calendar.calendarlist.readonly
https://www.googleapis.com/auth/calendar.events.freebusy
https://www.googleapis.com/auth/calendar.events.readonly
https://www.googleapis.com/auth/calendar.calendars

Worker 会自动添加 email profile,因为回调会使用 Google 的 user-info 端点来识别已授权用户。

Google 授权请求还使用了 access_type=offline 和 prompt=consent,所以 Google 会返回刷新令牌。

Related MCP server: google-mcp-server

本地机密

复制示例文件:

cp .dev.vars.example .dev.vars

设置:

GOOGLE_CLIENT_ID=<Google OAuth web client ID>
GOOGLE_CLIENT_SECRET=<Google OAuth client secret>
COOKIE_ENCRYPTION_KEY=<strong random secret>
HOSTED_DOMAIN=<optional Google Workspace domain restriction>

GOOGLE_OAUTH_SCOPES 和 GOOGLE_MCP_URL 是 wrangler.jsonc 中的非机密 Worker 变量。

Google Cloud OAuth 客户端

请使用 Google OAuth Web 应用客户端。

已授权的重定向 URI 必须是此 Worker 或隧道的公共主机名,并另接上 /callback:

https://mcp-auth.example.com/callback

将上面列出的 Calendar 作用域添加到 Google Auth Platform 的 consent/数据访问配置中。

在本地运行

安装依赖并生成 Worker 类型:

npm install
npm run cf-typegen

在 5555 端口上本地启动 Wrangler:

npm run dev

本地端点是:

http://localhost:5555/mcp

OAuth 需要公共 HTTPS 回调,因此要在本地进行端到端测试,请使用 Cloudflare Tunnel。

稳定的命名隧道

建议使用稳定的主机名,因为必须将同一个回调注册到 Google Cloud。

npx wrangler dev --tunnel-name=mcp-google-auth --tunnel

将命名隧道主机名配置为路由到 Wrangler 开发服务器。例如:

https://mcp-auth.example.com  ->  local Wrangler dev server

然后注册:

https://mcp-auth.example.com/callback

作为 Google OAuth 重定向 URI。

提供给 Codex 的 MCP URL 是:

https://mcp-auth.example.com/mcp

Codex 配置

由于此 Worker 是 Codex 眼中的 OAuth 授权服务器,因此 Codex 不需要 Google 客户端 ID 或客户端密钥。

[mcp_servers.google_calendar_proxy]
enabled = true
url = "https://mcp-auth.example.com/mcp"
auth = "oauth"

然后进行身份验证:

codex mcp login google_calendar_proxy

预期流程如下:

  1. Codex 发现此 Worker 的 OAuth 端点。

  2. Codex 在此 Worker 上注册/进行身份验证。

  3. Worker 将浏览器引导到 Google。

  4. Google 返回 Worker/隧道上的 /callback。

  5. Worker 使用 GOOGLE_CLIENT_SECRET 换取 Google 的授权代码。

  6. Codex 收到 Worker 签发的 OAuth 令牌。

  7. 对 /mcp 的调用会使用用户的 Google 访问令牌转发到 Google 官方 Calendar MCP。

令牌刷新行为

Google 的刷新令牌保留在加密的 OAuth 授权属性中。代理会维护一个有界、隔离本地(isolate-local)的 Google 访问令牌 LRU 缓存;当条目到达刷新窗口时会将其移除,并将缓存在最多保留 100 个用户。如果存储的访问令牌已过期,或 Google 的 MCP 返回 401,Worker 会使用 Google 刷新令牌加上 Worker 端的客户端密钥来生成新的 Google 访问令牌,并重试一次。

内存缓存只是优化。新的 Worker 隔离区始终可以从加密的授权属性刷新令牌。

旧版授权

在支持刷新令牌之前创建的 OAuth 授权只包含原始的 Google 访问令牌和用户元数据。代理会引用这些授权,并在 Google 仍然接受时继续使用其现有访问令牌。一旦 Google 拒绝该令牌,Worker 会返回 401 invalid_token,因此 MCP 连接可以重新授权,而不是在缺少凭据的情况下尝试刷新。

Related MCP Connectors

Related MCP Servers