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.jsoncGOOGLE_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=offlineprompt=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_SCOPESGOOGLE_MCP_URLwrangler.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 连接可以重新授权,而不是在缺少凭据的情况下尝试刷新。

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Streamable HTTP MCP server for Google Calendar and Sheets with OAuth login.

  • Hosted Google Calendar MCP server for AI agents. No self-hosting or Google Cloud setup.

  • Self-hosted federated MCP gateway: one OAuth 2.1 MCP server in front of N apps, user-level scopes.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/REVREBEL/cloudflare-mcp-google-auth'

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