Skip to content

feat(google-workspace): bundle our REST-based Google MCPs (8 services, 162 tools)#422

Open
JonasJesus42 wants to merge 1 commit intomainfrom
JonasJesus42/google-workspace-rest-bundle
Open

feat(google-workspace): bundle our REST-based Google MCPs (8 services, 162 tools)#422
JonasJesus42 wants to merge 1 commit intomainfrom
JonasJesus42/google-workspace-rest-bundle

Conversation

@JonasJesus42
Copy link
Copy Markdown
Contributor

@JonasJesus42 JonasJesus42 commented May 5, 2026

Summary

Replaces the previous google-workspace implementation that proxied Google's official MCP servers (Calendar/Chat/Drive/Gmail/People) with a bundle of our existing per-service REST-based Google MCPs. Brings Workspace from 5 services to 8 while dropping the OAuth-consent-screen issues that left most tools returning 403.

Why

Live testing of the official-MCP wrapper hit "caller does not have permission" on 4 of 5 services. The fundamental issue: Google's MCPs don't support Dynamic Client Registration, and the 26-scope union we requested didn't match what was actually configured on the OAuth client's consent screen — Google silently dropped the rest.

Our existing standalone Google MCPs (google-calendar, google-gmail, etc.) already work in production with their REST API integrations. Composing them gives us the "1 login for everything" UX that motivated google-workspace in the first place, with no proxy layer in the way.

What's in the bundle now

Service Prefix Tools Source
Calendar calendar_* 20 google-calendar
Gmail gmail_* 26 google-gmail (basicTools only — no webhook triggers)
Drive drive_* 15 google-drive
Docs docs_* 13 google-docs
Sheets sheets_* 55 google-sheets
Slides slides_* 12 google-slides
Forms forms_* 9 google-forms
Meet meet_* 12 google-meet

Total: 162 tools, 1 OAuth login.

What got dropped

  • Chat / People — their Google official MCPs need additional OAuth-consent-screen verification we haven't completed. Will come back in a separate google-workspace-official MCP that wraps the upstream Google endpoints once verification lands.
  • gmail send — same as before; this MCP only creates drafts.

Implementation

The composition is a small helper:

// server/lib/prefix-tool.ts
export function prefixToolFactory(factory, prefix) {
  return (env) => {
    const tool = factory(env);
    return { ...tool, id: `${prefix}_${tool.id}` };
  };
}

Each child MCP's tools is Array<(env) => Tool>. We invoke the factory with workspace's env (structurally compatible — every Google MCP just reads MESH_REQUEST_CONTEXT.authorization) and clone the result with a prefixed id.

Side changes to make composition possible

  • google-gmail/server/tools/index.ts — split the existing tools array into basicTools (no webhook triggers) + tools (with triggers). Workspace imports basicTools because it doesn't have the Workers KV binding the trigger machinery requires.
  • google-{gmail,drive,docs,sheets,slides,forms,meet}/package.json — add ./tools and ./constants exports so workspace can import them.

Removed (no longer needed)

  • google-workspace/server/lib/{mcp-proxy,json-schema-to-zod,wrap-tool}.ts
  • google-workspace/server/scripts/generate-tools.ts
  • google-workspace/server/tools/generated/*.json

Prompts updated

Per-service agent guides now cover Docs/Sheets/Slides/Forms/Meet (Chat/People removed). Two new user templates: new_deck_from_outline and create_form and create_meet_for_event.

Test plan

  • bun scripts/check.ts on all 9 affected MCPs — all pass
  • bun run build succeeds (2.45 MB / 513 modules)
  • Local boot: tools/list returns 162 tools across 8 prefixed namespaces
  • After deploy: re-authenticate an existing google-workspace connection and verify a sample tool from each service works (smoke test calendar/gmail/drive/docs/sheets/slides/forms/meet)

Backwards compatibility

The MCP keeps its name (google-workspace) and connection URL (sites-google-workspace.decocache.com/mcp). Existing installs continue to work after re-authentication (different scope set). Tool ids change shape — agents using prior Chat/People tools will need to switch to the standalone Chat/People MCPs (or wait for google-workspace-official).

🤖 Generated with Claude Code


Summary by cubic

Replaces the proxy to Google’s official MCPs with a bundled set of our REST-based Google MCPs. Expands google-workspace to 8 services and 162 tools under one OAuth login while removing the consent-screen issues that caused 403s.

  • New Features

    • Bundle google-calendar, google-gmail (basic tools), google-drive, google-docs, google-sheets, google-slides, google-forms, google-meet → 162 tools
    • Service-prefixed tool IDs: calendar_*, gmail_*, drive_*, docs_*, sheets_*, slides_*, forms_*, meet_*
    • Single OAuth flow using the deduped union of scopes from all bundled services
    • Prompts updated for Docs/Sheets/Slides/Forms/Meet + new templates: new deck from outline, create form, create Meet for event
  • Migration

    • Re-authenticate existing google-workspace connections (scope set changed)
    • Chat and People removed; use their standalone MCPs or wait for google-workspace-official
    • Gmail: still draft-only (no send) and no webhook triggers in the workspace bundle

Written for commit c201ba8. Summary will update on new commits.

…, 162 tools)

Replaces the previous implementation that proxied Google's official MCP
servers (Calendar/Chat/Drive/Gmail/People) — that approach was blocked
because Google's MCP endpoints don't support Dynamic Client Registration
and our requested 26-scope union ran into OAuth-consent-screen
configuration drift, leaving most services with "caller does not have
permission" errors.

The new google-workspace composes the existing per-service Google MCPs
already shipping in this monorepo:

  google-calendar/tools       → calendar_*  (20 tools)
  google-gmail/tools (basic)  → gmail_*     (26 tools)
  google-drive/tools          → drive_*     (15 tools)
  google-docs/tools           → docs_*      (13 tools)
  google-sheets/tools         → sheets_*    (55 tools)
  google-slides/tools         → slides_*    (12 tools)
  google-forms/tools          → forms_*     (9 tools)
  google-meet/tools           → meet_*      (12 tools)

A small `prefix-tool.ts` helper clones each child tool factory's output
with a service-prefixed id so collisions across services are resolved
without modifying the upstream packages. `createGoogleOAuth` runs the
PKCE flow with the union of scopes from all eight services.

Chat and People are intentionally dropped — their Google official MCPs
require additional OAuth consent-screen verification we haven't
completed. They'll come back in a separate `google-workspace-official`
MCP that wraps the upstream Google endpoints once verification lands.

Side changes to enable the composition:

- google-gmail/.../tools/index.ts: split the existing tools array into
  basicTools (no webhook triggers) + tools (with triggers). Workspace
  imports basicTools because it doesn't have the Workers KV binding the
  trigger machinery requires.
- google-{gmail,drive,docs,sheets,slides,forms,meet}/package.json: add
  ./tools and ./constants exports so workspace can import them.

Removed (no longer needed):

- google-workspace/server/lib/{mcp-proxy,json-schema-to-zod,wrap-tool}.ts
- google-workspace/server/scripts/generate-tools.ts
- google-workspace/server/tools/generated/*.json

Prompts updated: drop chat/people guides, add per-service guides for
Docs/Sheets/Slides/Forms/Meet, plus user templates for new-deck and
form-from-questions.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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