Skip to main content
Glama

Google Cloud Services MCP — Google Docs, Sheets & Drive for AI Clients

9 tools for the Google Docs, Sheets, and Drive APIs — read, write, and manage files with a service account, no OAuth consent screen required — for Claude Desktop, Claude Code, and any MCP client.

by Jan Ivan Simoy


Unofficial. This is an independent, community-built project — not affiliated with, endorsed by, or sponsored by Google.

What is this?

Google Cloud Services MCP is a Model Context Protocol server that gives AI assistants structured read/write access to Google Docs, Sheets, and Drive — backed by a Google Cloud service account, not a 3-legged OAuth user flow. There's no browser consent screen and no refresh-token dance: share a file with the service account's email address and it's accessible immediately.

It supports multiple clients/service accounts side by side — each gets its own config file, and one server instance serves one config — so a single checkout can back several Google Cloud projects without editing code.

Supported platform: any MCP client on macOS, Linux, or Windows with Python 3.9+.


Related MCP server: gdrive-mcp-server

Tools

Category

Tools

What you can do

Docs

3

Read any Doc as plain text; replace or append its body from markdown — real headings, bullet lists, and native bordered tables, not just raw text

Sheets

4

Read a range, overwrite it, append rows, or clear it

Drive

2

List files in a folder; read/export any file (Docs/Sheets as text, .docx parsed, anything else downloaded raw)

Tool

Description

doc_read

Read a Doc's full text. Tries the Docs API first, falls back to a Drive plain-text export for restricted or third-party-converted docs

doc_write

Replace a Doc's body from markdown — #/##/### headings, - /* bullets, and | a | b | tables become real Docs formatting, with an auto-bolded header row on tables

doc_append

Same markdown rendering as doc_write, appended to the end instead of replacing

sheet_read

Read a range (default A1:ZZ) as rows of values

sheet_write

Overwrite a range with values

sheet_append

Append rows after the last row with data in a range

sheet_clear

Clear all values in a range

drive_list

List files in a folder (or Drive root/shared drive if none given)

drive_read

Read/export any file — native Docs/Sheets as text, .docx parsed via python-docx, anything else downloaded raw

Every tool accepts a full Google URL or a bare document/spreadsheet/file ID — URL extraction is handled internally.


Requirements

Requirement

Version

Python

3.9 or later

Google Cloud project

with the Docs, Sheets, and Drive APIs enabled

Service account

with a downloaded JSON key


Authentication

This server uses a service account — no interactive OAuth consent screen, no refresh tokens to manage. Setup:

  1. In Google Cloud Console, create/select a project and enable the Google Docs API, Google Sheets API, and Google Drive API (APIs & Services → Library).

  2. Create a service account (IAM & Admin → Service Accounts) and generate/download its JSON key.

  3. Share each target Doc, Sheet, or Drive folder with the service account's email address (the client_email field in the key file) — Viewer access for reading, Editor access for doc_write/doc_append.

  4. Point service_account_key at the downloaded key file in your config (see Configuration).


Installation

git clone https://github.com/jimsimoy/google-cloud-services-mcp.git
cd google-cloud-services-mcp
pip install -r requirements.txt

cp config.example.json configs/default.json
# edit configs/default.json: set service_account_key to your downloaded key file's path

Run directly (mainly for debugging — an MCP client normally launches this for you):

python3 server.py --config configs/default.json

Configuration

Configs live under configs/ — one JSON file per client or service account. One server instance serves one config, chosen with --config at launch. Everything in configs/ is gitignored except the folder itself; only config.example.json at the repo root is tracked.

config.example.json documents the schema:

{
  "service_account_key": "/absolute/path/to/service-account-key.json",
  "scopes": [
    "https://www.googleapis.com/auth/documents",
    "https://www.googleapis.com/auth/spreadsheets",
    "https://www.googleapis.com/auth/drive"
  ],
  "defaults": {
    "spreadsheet_range": "A1",
    "doc_export_format": "text"
  }
}

To serve a second client/service account, copy it again as configs/acme.json and point a second MCP client entry at --config configs/acme.json.


Client Setup

{
  "mcpServers": {
    "google-cloud-services": {
      "command": "python3",
      "args": ["/path/to/google-cloud-services-mcp/server.py", "--config", "configs/default.json"]
    }
  }
}

Restart your MCP client after saving. The 9 tools will appear automatically.


Usage Examples

Read a doc

Read the Google Doc at https://docs.google.com/document/d/1AbC.../edit

Publish a markdown report to a doc

Write this report to Google Doc 1AbC... : <markdown content>

Log a row to a tracking sheet

Append a row to Sheet1!A1 in spreadsheet 1XyZ...: 2026-09-13, done

List and export files from a Drive folder

List the files in Drive folder FOLDER_ID, then read the first PDF you find

Security

  • Credentials live only in configs/*.json, which are entirely gitignored — only the placeholder config.example.json is tracked.

  • The service account key file itself should be stored outside the repo. Treat it like a password: anyone holding it can act as that account against every file it's been shared on.

  • doc_write deletes and replaces the entire body of the target Doc — there's no undo beyond Google Docs' own built-in version history.

  • Output this server downloads or exports belongs in artifacts/ (gitignored) so working files never end up in a commit.


Project Structure

server.py                  # MCP server entry point and tool definitions
google_cloud_services.py   # Docs/Sheets/Drive client library (pure functions, no protocol code)
config.example.json        # config template — copy into configs/
configs/                   # per-client/service-account configs (gitignored)
artifacts/                 # scratch space for downloaded/exported files (gitignored)
tests/                     # offline pytest suite — no credentials or network needed

The server communicates over stdio using JSON-RPC 2.0, the standard MCP transport.


Development

python3 -m venv .venv
./.venv/bin/pip install -r requirements.txt pytest
./.venv/bin/python -m pytest -q

51 tests, all offline — every Google Docs/Sheets/Drive API call is faked via a mocked build() (unittest.mock.MagicMock), so nothing here touches the network or needs a real service account. Coverage: extract_id_from_url's URL patterns, the markdown-to-Docs conversion (_parse_markdown_segments, _parse_simple_markdown) including multi-table and malformed-table edge cases, the table-insertion cell-fill-order logic (_insert_table_at fills highest-index cells first so earlier inserts never shift positions not yet written), doc_read's Docs-API-then-Drive- fallback behavior, every Sheets operation, and drive_read's three branches (native Docs/Sheets export, a real in-memory .docx parsed through python-docx, and the generic raw-download fallback). load_config/get_credentials are covered too (missing-file and credential-wiring paths).


A note on testing

Beyond the automated suite above: this was built directly against the official Google Docs v1, Sheets v4, and Drive v3 REST APIs via google-api-python-client. The markdown-to-Docs writer (headings, bullet lists, and native bordered tables with an auto-bolded header row) and the URL-or-bare-ID handling have both been exercised against real Google accounts in production use, prior to this repo's creation.

The MCP layer itself was verified end-to-end using the official mcp Python client SDK against a real server subprocess: the initialize handshake, tools/list (all 9 tools returned with correct schemas), a live authenticated tool call (drive_list returning real Drive data), a live API error surfaced correctly as isError: true (sheet_read on a nonexistent spreadsheet), SDK-level input validation rejecting a call missing a required argument, and an unknown tool name returning a clean error instead of crashing the server.


License

MIT — free to use, modify, and distribute.


Report a Bug · Request a Feature

Related MCP Connectors

Related MCP Servers