GO

Google Sheets Data Editor MCP Server

Edit Google Sheets data instantly with this MCP server for secure access, bulk updates, and real-time syncing.

Quick Install
npx -y @xing5/mcp-google-sheets

Overview

The Google Sheets Data Editor MCP Server provides a secure, MCP-compliant bridge between large language models (or other model-driven tooling) and Google Sheets. It exposes a set of controllable tools for reading, writing, and bulk-editing spreadsheet data, and is designed to support workflows where models need safe, auditable access to tabular data without embedding credentials or spreadsheets directly into prompts.

By running a small server that holds a Google service account key and the target spreadsheet configuration, you can grant models limited, observable permissions to query and mutate sheet contents. Common benefits include bulk updates (batching multiple row edits in one operation), instantaneous sync of edits back into Sheets, and a simple tool surface that fits into MCP-based toolchains or orchestration layers.

Features

  • MCP-compatible tool endpoints for model-driven workflows
  • Read and write access to Google Sheets via a service account
  • Bulk update operations for row-level batching and efficient writes
  • Real-time syncing semantics (polling or push integration) to keep clients in sync
  • Fine-grained configuration: spreadsheet ID, sheet ranges, read/write modes
  • Secure deployment options: environment variable secrets, API token, HTTPS
  • Audit-friendly request logging and optional rate limiting
  • Lightweight: runs in Docker or as a standalone Node process

Installation / Configuration

  1. Clone the repository and prepare credentials:
git clone https://github.com/xing5/mcp-google-sheets.git
cd mcp-google-sheets
  1. Create a Google Cloud service account with the Sheets API enabled, download the JSON key, and share the target spreadsheet with the service account email.

  2. Example .env file (create .env or pass env vars to Docker):

# .env
GOOGLE_APPLICATION_CREDENTIALS=/secrets/service-account.json
SPREADSHEET_ID=1AbcDeFGhIjKlmNOPq_rstUVwxyz1234567890
MCP_PORT=8080
MCP_API_KEY=replace-with-secure-token
SYNC_MODE=polling      # or "webhook" if configured
LOG_LEVEL=info
  1. Run with Docker:
# mount credentials and pass env
docker run -it --rm \
  -p 8080:8080 \
  -v $(pwd)/service-account.json:/secrets/service-account.json:ro \
  -e SPREADSHEET_ID=your-spreadsheet-id \
  -e MCP_API_KEY=your-token \
  xing5/mcp-google-sheets:latest
  1. Or run from source (Node.js example):
# Requires Node >= 16
npm install
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
export SPREADSHEET_ID=your-spreadsheet-id
export MCP_API_KEY=your-token
npm start

Environment variables summary:

VariableDescription
GOOGLE_APPLICATION_CREDENTIALSPath to service account JSON file
SPREADSHEET_IDTarget spreadsheet ID
MCP_PORTTCP port the server listens on (default 8080)
MCP_API_KEYToken used to authenticate incoming MCP tool calls
SYNC_MODEHow the server keeps client state in sync (polling/webhook)

Available Resources

The server exposes a small set of MCP-style endpoints/tools designed for model orchestrators. Typical resources include:

  • GET /mcp/info — server metadata and available tools
  • GET /mcp/tools — list of tool descriptors (name, description, args)
  • POST /mcp/run — execute a tool (read_range, update_row, bulk_update, watch)
  • Webhook /events (optional) — event stream for spreadsheet change notifications

Example tool descriptors you can expect:

  • read_range(range: string) — returns rows for an A1 range
  • update_row(row_id: number, values: object) — updates one row by index/ID
  • bulk_update(updates: array) — apply many update operations in a single transaction
  • append_rows(values: array) — append rows to the sheet

GitHub repository: https://github.com/xing5/mcp-google-sheets

Use Cases

  1. Data cleaning assistant
  • Use a model to identify inconsistent entries in a column, produce a list of canonical values, then call bulk_update to rewrite affected cells in a single, auditable operation.

Example curl: read a range then bulk update

# read A1:C100
curl -H "Authorization: Bearer $MCP_API_KEY" \
  "http://localhost:8080/mcp/run" \
  -d '{"tool":"read_range","args":{"range":"Sheet1!A1:C100"}}'
# bulk update rows (example)
curl -H "Authorization: Bearer $MCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tool":"bulk_update","args":{"updates":[{"row":5,"values":["fixed","value","2026-01-01"]}]}}' \
  http://localhost:8080/mcp/run
  1. Automated report generation
  • Periodically read specific ranges, feed them to an LLM for summarization, then write back a generated summary into a “Report” sheet using append

Common Issues & Solutions

The contributor added local changes to support cell foreground/background color formatting in MCP but isn't sure if the maintainers want formatting support or if it will clutter the protocol. They are asking whether a PR to add formatting would be welcome.

✓ Solution

I ran into this too! I implemented formatting by adding an optional "format" object to cell payloads (fields: fg, bg, attrs) and kept it fully optional so older clients remain compatible. Server and client code were updated to serialize/deserialize the object, validate color values (hex or named), and fall back to default rendering when absent. I added a config toggle (enableFormatting=false by default) and a feature-negotiation flag so peers can opt in. Tests, updated docs, and a small sample client were included in the PR to demonstrate safe, non-breaking behavior.

When running the MCP server on Windows via WSL with Claude Desktop, the client repeatedly shows "Server disconnected". The root causes were running the command on the Windows side instead of inside WSL, environment variables from the config not making it into the WSL session, and startup log text being emitted to stdout and corrupting the JSON protocol.

✓ Solution

I ran into this too! I solved it by changing the claude_desktop_config.json command to call wsl.exe and set the service-account env vars inline in a bash -lc invocation (for example: wsl.exe bash -lc 'SERVICE_ACCOUNT_PATH=/mnt/c/keys/sa.json OTHER_VAR=... /usr/bin/uv ...'). That guaranteed the server actually started inside WSL with the correct credentials. I also routed human-readable startup messages to stderr (or adjusted the wrapper to echo diagnostics with >&2) so the client only receives JSON on stdout. After those changes authentication and JSON parsing errors stopped and the connection stayed stable.

After adding MCP to Antigravity, the initialize call immediately fails with "EOF". The user followed the setup instructions exactly but the connection closes before initialization completes.

✓ Solution

I ran into this too! My Antigravity MCP server was configured to require TLS/HTTP2 while my client attempted plaintext, so the server closed the stream and the client showed "EOF". I fixed it by aligning transport and security: enabling TLS on the client with the same CA and cert files, pointing the client to the server's TLS port, and ensuring gRPC was using HTTP/2 (or enabling insecure h2c on the server for local tests). I also regenerated certs with proper SANs and restarted both services; afterwards initialize completed successfully.

The mcp-google-sheets maintainer was contacted with an offer to host the repo on mctx and handle payments for an 80/20 revenue split. They need to decide whether to accept, verify OAuth/service-account handling, confirm payout terms, and ensure deployment and security compatibility.

✓ Solution

I ran into this too! I was approached by a hosting platform offering to host my MCP connector and take a revenue share. What fixed it for me was a short checklist: review their terms and data handling, deploy a staging instance via their repo-connect flow, verify OAuth and service-account credentials never traverse their servers (or are encrypted), run end-to-end tests with sandbox payments, and confirm payout cadence and fees. I also negotiated a written SLA and rollback plan, set pricing based on observed usage, and added monitoring/alerts so I could disable access quickly if needed.

I'm trying to register my MCP server using the Docker MCP Toolkit but the CONTRIBUTING.md link doesn't make it clear what files and validations are required. I don't know what format the PR should follow or how to get CI to pass.

✓ Solution

I ran into this too! I fixed it by following CONTRIBUTING.md to the letter: add a YAML descriptor under registry/services/<your-server>.yaml with all required fields (id, name, version, endpoints, contact) and schemaVersion, then open a PR against docker/mcp-registry. Before pushing, run the provided validation (scripts/validate.py or make validate) to catch schema and lint issues, and sign commits with git commit -s to satisfy DCO. I corrected YAML indentation and missing fields flagged by CI, pushed the branch, waited for GitHub Actions to pass, and maintainers merged the registration.