github taylorwilsdon/google_workspace_mcp v1.22.2

5 hours ago

Release v1.22.2

A maintenance release focused on ending the hourly OAuth 2.1 re-auth loop, returning complete data from Sheets and Gmail, and adding optional OpenTelemetry tracing. Also includes a security dependency bump and new Google Docs table header controls.

Authentication

Fixed: OAuth 2.1 proxy sessions no longer force a re-auth every hour (#942, fixes #886 and #775)

When running behind the FastMCP OAuth proxy, the server was building Google credentials without an upstream refresh token, so every session died when Google's ~1 hour access token expired and clients were bounced back through the full auth flow.

The session store now walks FastMCP 3.x's real token chain — the inbound reference JWT's jti_jti_mapping_store_upstream_token_store — to recover the upstream access and refresh tokens, producing credentials that refresh transparently. ensure_session_from_access_token() is now async (it awaits the proxy's key-value stores); callers in auth_info_middleware and service_decorator were updated accordingly. Requires fastmcp>=3.4.4.

Google Sheets

  • read_sheet_values no longer stops at 50 rows (#955) — the tool fetched everything in range_name but silently truncated the rendered output to the first 50 rows with an "... and N more rows" footer. It now returns every row it fetched; callers bound the volume with range_name (default A1:Z1000).
  • Reject cell references passed as column letters (#964, thanks @syf2211) — _column_to_index accepted inputs like A1 and quietly computed a garbage index from the digits. Column parsing is now strict (^[A-Za-z]+$), and A1 range/sheet-title parsing switched from .match() to .fullmatch() so trailing junk raises a clear UserInputError instead of being ignored.

Gmail

  • Untruncated message export (#939, thanks @123andy) — get_gmail_message_content gained a full: bool parameter that returns the complete message with no truncation limit. Over HTTP the body is written to attachment storage and handed back as a download URL; over stdio you get the file path; in stateless mode (no storage) it's inlined and explicitly labeled as complete. Works with all three body_format values, including raw, which saves the byte-exact RFC 5322 message as .eml. Encoding and file writes run on a worker thread so large exports don't block the event loop.
  • get_gmail_thread_content now includes To/Cc (#970, fixes #693) — recipient headers were dropped from thread output, making it impossible to tell who was on a message. Thread formatting now goes through _extract_headers and always prints To:/Cc:, marking them [not present in Gmail response] when Gmail genuinely omits them rather than leaving the reader guessing. Repeated To/Cc headers are merged instead of last-one-wins, and thread ownership analysis matches header names case-insensitively (Gmail does not guarantee casing).

Google Docs

Table header row support (#947, thanks @pmgagne) — two new batch_update_doc operations:

  • pin_table_header_rows — repeat the leading N rows of a table after every page break (0 unpins). This is the writable Docs API request for the header state that TableRowStyle.tableHeader only reports; sending tableHeader on updateTableRowStyle returns a 400.
  • update_table_row_style — set min_row_height for specific rows.

create_table_with_data also accepts header_rows to pin headers at creation time, and now reports PARTIAL SUCCESS (with the effective index) when the table is created but a follow-up styling step doesn't fully apply.

Telemetry

Optional OpenTelemetry tracing (#938, thanks @DrFaust92) — FastMCP is already instrumented, but its spans are no-ops without a configured TracerProvider. The new core/telemetry.py wires one up from the standard OTEL_* environment variables so tool-call spans export to an OTLP collector.

pip install "workspace-mcp[otel]"     # already in the Docker image
export OTEL_EXPORTER_OTLP_ENDPOINT="http://otel-collector:4317"
export OTEL_EXPORTER_OTLP_PROTOCOL="grpc"   # or "http/protobuf"

Strictly opt-in and off by default: with no endpoint set nothing is configured, a provider installed by auto-instrumentation is left alone, and a missing SDK logs a hint instead of failing startup. The README's security and licensing sections were updated to reflect that tracing exports only to an endpoint you configure yourself.

Dependencies

  • Security bumps (#956) — mcp 1.28.1, pyasn1 0.6.4, pypdf 6.14.2.
  • fastmcp raised to >=3.4.4 (required by the OAuth fix above).
  • httplib2 0.31.2 → 0.32.0 (#969, @dependabot).

Docs

  • MCP Toplist rank badge added to the README (#965, thanks @chrstphe).

Upgrade notes

  • ensure_session_from_access_token() is now a coroutine. If you import it from auth.oauth21_session_store in your own code, add await.
  • read_sheet_values output can be much larger than before. If you relied on the implicit 50-row cap, narrow range_name explicitly.

New Contributors

As always, thanks to our new contributors!

Full Changelog: v1.22.1...v1.22.2

Don't miss a new google_workspace_mcp release

NewReleases is sending notifications on new releases.