Skip to content

feat(google-workspace): one OAuth login fanning out to 5 official Google MCP servers#418

Merged
JonasJesus42 merged 4 commits into
mainfrom
JonasJesus42/google-workspace-mcp
May 5, 2026
Merged

feat(google-workspace): one OAuth login fanning out to 5 official Google MCP servers#418
JonasJesus42 merged 4 commits into
mainfrom
JonasJesus42/google-workspace-mcp

Conversation

@JonasJesus42
Copy link
Copy Markdown
Contributor

@JonasJesus42 JonasJesus42 commented May 5, 2026

Summary

  • New MCP google-workspace proxies JSON-RPC tools/call to Google's official MCP endpoints (calendarmcp.googleapis.com, chatmcp..., drivemcp..., gmailmcp..., people.googleapis.com).
  • One OAuth login covering all 5 services — Google Workspace credentials live in this MCP's secrets, not in the mesh core. No changes to santa-fe.
  • ~33 tools exposed under prefixes calendar_*, chat_*, drive_*, gmail_*, people_*. Adding a 6th Google service later is a 2-line change in constants.ts plus bun run generate-tools.

Why not connect Google's MCPs directly to mesh?

The official Google MCP endpoints don't support Dynamic Client Registration (RFC 7591) and require client_secret_post, while mesh's current McpOAuthProvider is a public PKCE client that relies on DCR. Wrapping them in our own MCP keeps the BYOC flow and secrets server-side, with zero mesh changes.

How it works

  1. server/scripts/generate-tools.ts fetches tools/list and PRM scopes_supported from each backend (no auth needed for these endpoints) and writes snapshots to server/tools/generated/<service>.json. Snapshots are committed for reproducible builds.
  2. At boot, the runtime reads the snapshots, converts JSON Schema → Zod with a small inline converter (server/lib/json-schema-to-zod.ts), and registers each tool through createPrivateTool.
  3. On tools/call, the wrapper proxies JSON-RPC to the upstream backend with the user's Bearer token (server/lib/mcp-proxy.ts).
  4. OAuth flow reuses @decocms/mcps-shared/google-oauth — PKCE with refresh-token rotation handled by the existing helper.

Test plan

  • Set GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET for the deployed instance (Web client with redirect URI for sites-google-workspace.decocache.com).
  • In a mesh org, install Google Workspace from the registry and authenticate.
  • Verify the consent screen lists scopes for Calendar, Chat, Drive, Gmail and People.
  • After consent, smoke-test one tool per service:
    • calendar_list_events with { calendarId: "primary" }
    • gmail_list_messages with { maxResults: 5 }
    • drive_list_files
    • people_list_directory_people
    • chat_list_spaces
  • Force expires_at in the past and confirm refresh works transparently.
  • Revoke the token via Google Account settings → next call returns the "401 Unauthorized — please re-authenticate" error from proxyMcpCall.

Notes

  • Google's chatmcp returns duplicate entries (list_messages, search_conversations) in tools/list; we dedupe by prefixed name in server/tools/index.ts.
  • bun run generate-tools is the one command needed to refresh tool definitions when Google updates their MCPs. CI could later run it and fail on diff.
  • This PR contains no Google-specific OAuth changes to the mesh core — the BYOC fix in santa-fe (supporting non-DCR providers in custom connections) can be tackled separately.

🤖 Generated with Claude Code


Summary by cubic

Adds a new google-workspace MCP that uses one OAuth login to fan out to Google’s official MCP servers (Calendar, Chat, Drive, Gmail, People), exposing ~33 prefixed tools and keeping Google credentials server-side. Marks the app as official in the registry and removes deprecated baseUrl/paths from tsconfig to quiet CI.

  • New Features

    • Proxies JSON-RPC tools/call to calendarmcp.googleapis.com, chatmcp.googleapis.com, drivemcp.googleapis.com, gmailmcp.googleapis.com, and people.googleapis.com.
    • Single OAuth via @decocms/mcps-shared/google-oauth (PKCE + refresh) with merged scopes across all services.
    • Snapshot-based tool generation and JSON Schema → Zod conversion; tools registered via createPrivateTool, duplicates from Chat MCP deduped; extend via constants.ts + bun run generate-tools.
    • Adds README.md and auto-generated TOOLS.md; generator writes the catalog using unauthenticated tools/list and RFC 9728 PRM scopes.
    • Registry: marked as official in app.json to show the official badge.
  • Migration

    • Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET for the deployed google-workspace site.
    • Publish/install the google-workspace app and authenticate once to grant Calendar, Chat, Drive, Gmail, and People scopes.
    • No mesh core changes required.

Written for commit 9bbce94. Summary will update on new commits.

JonasJesus42 and others added 4 commits May 5, 2026 05:41
…gle MCP servers

Adds a new MCP that holds the Google OAuth client credentials server-side
and proxies JSON-RPC tools/call to the official Google MCP endpoints
(calendarmcp, chatmcp, drivemcp, gmailmcp, people). After a single consent
screen with all required scopes, ~33 tools become available under prefixes
calendar_*, chat_*, drive_*, gmail_*, people_*.

- Reuses createGoogleOAuth from @decocms/mcps-shared (PKCE + refresh).
- generate-tools script snapshots tools/list and PRM scopes_supported from
  each backend; runtime reads the snapshots, converts JSON Schema to Zod via
  a small inline converter, and registers each tool through createPrivateTool.
- Dedupes duplicate entries returned by Google's chat backend.

Adding a new Google service later is two lines in constants.ts plus a
re-run of generate-tools. Existing users get a re-consent prompt only for
the new scopes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The README explains how the snapshot pattern works and makes the
`bun run generate-tools` requirement explicit — every time Google updates
one of their MCP servers, the snapshot must be refreshed and committed.

The generator now also produces TOOLS.md alongside the JSON snapshots, so
the full tool catalog is visible from GitHub and the registry without
having to boot the server. Both Google's `tools/list` and the RFC 9728 PRM
endpoint are reachable without auth, so this preview costs nothing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
CI's TS version flags `baseUrl` as deprecated. The block also declared a
`server/*` alias we never used — every import inside the package is
already relative — so the cleanest fix is to remove the block entirely
rather than adding `ignoreDeprecations`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This MCP wraps Google's own official MCP servers
(calendarmcp/chatmcp/drivemcp/gmailmcp/people.googleapis.com), so the
"official" badge in the registry is warranted.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@JonasJesus42 JonasJesus42 merged commit 5a8af3e into main May 5, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant