- The server registers 20 tools (9 read, 11 write) behind a tool-registration wrapper at server.py:190-218.
- All five range-building call sites splice sheet names into A1 ranges unquoted (server.py:251, 305, 346, 391, 737), breaking on any tab titled with a space or apostrophe.
- share_spreadsheet defaults send_notification to True despite a destructiveHint=True annotation (server.py:1034-1037) — the README never states the default.
- The ENABLED_TOOLS / --include-tools filter silently drops misspelled tool names with no error (server.py:190-218).
- Google now ships its own first-party Sheets MCP server (sheetsmcp.googleapis.com/mcp/v1) that is OAuth-client-scoped, one server per Workspace product, unlike xing5's single service-account-key setup covering both Sheets and Drive.
01 What mcp-google-sheets is and who ships it
Use xing5/mcp-google-sheets for self-hosted, service-account-authenticated Sheets and Drive automation — not for spreadsheets whose sheet names contain spaces or apostrophes, since five of its 20 tools — get_sheet_data, get_sheet_formulas, update_cells, batch_update_cells, and get_multiple_sheet_data — build their A1 range with an unquoted f-string that the Sheets API will reject the moment a tab is titled something like "Q3 Sales." mcp-google-sheets is a community-maintained Python MCP server, built and maintained by xing5, that bridges MCP clients such as Claude Desktop to the Google Sheets and Google Drive APIs so an agent can create and edit spreadsheets. It is not Google's own product: Google now ships a first-party Sheets MCP server inside its Workspace MCP family (endpoint https://sheetsmcp.googleapis.com/mcp/v1, docs at developers.google.com/workspace/guides/configure-mcp-servers), a fact that is absent from this keyword's own top-10 search results but confirmed live. The repo (github.com/xing5/mcp-google-sheets) is MIT-licensed, and the GitHub API reported 960 stars and 230 forks on 2026-07-27, with the default branch's last commit dated 2026-05-14 and the latest release, v0.6.3, published the same day. Public record and source read on 2026-07-27.
02 Tools it exposes
The server registers 20 tools, gated through a tool-registration wrapper at src/mcp_google_sheets/server.py:190-218. Nine are read-only, eleven write to the spreadsheet or to Drive:
| Tool | What it does | Read/Write |
|---|---|---|
| list_spreadsheets | Lists spreadsheets visible to the authenticated account | Read |
| create_spreadsheet | Creates a new spreadsheet | Write |
| get_sheet_data | Reads cell values from a sheet | Read |
| get_multiple_sheet_data | Reads data from several sheets in one call | Read |
| get_multiple_spreadsheet_summary | Reads a summary across multiple spreadsheets | Read |
| get_sheet_formulas | Reads the underlying formulas rather than computed values | Read |
| update_cells | Writes values to a cell range | Write |
| batch_update_cells | Writes multiple non-contiguous ranges in one call | Write |
| batch_update | Applies a batch of spreadsheet-level update requests | Write |
| add_rows | Inserts rows into a sheet | Write |
| add_columns | Inserts columns into a sheet | Write |
| list_sheets | Lists the tabs inside a spreadsheet | Read |
| create_sheet | Creates a new tab | Write |
| rename_sheet | Renames a tab | Write |
| copy_sheet | Copies a tab, optionally into another spreadsheet | Write |
| find_in_spreadsheet | Searches for a value inside a spreadsheet | Read |
| search_spreadsheets | Searches Drive for spreadsheets | Read |
| list_folders | Lists Drive folders | Read |
| share_spreadsheet | Shares a spreadsheet with a user or group | Write |
| add_chart | Inserts a chart, with chart type, data range, axis labels and x/y position | Write |
get_sheet_formulas is the one server in this database that distinguishes formulas from computed values, which is what makes it usable for auditing a spreadsheet model rather than just reading its output.
03 Install and auth
Transport is stdio. Install verbatim:
uvx mcp-google-sheets@latestAuthentication is service-account or user OAuth: "Google service account (client_email) or user OAuth with Drive + Sheets scopes."
This is the axis the community server actually competes on: it needs nothing more than a bare service-account JSON key, where Google's own Sheets MCP server is OAuth-client-scoped, with one server per Workspace product.
04 What the source shows
Public record and source read on 2026-07-27: sheet names are spliced into A1 ranges with a bare f-string at all five range-building call sites, and the sheet name is never quoted anywhere in the file. Every one of these builds the same unguarded pattern, full_range = f"{sheet}!{range}" — src/mcp_google_sheets/server.py:251 (get_sheet_data), :305 (get_sheet_formulas), :346 (update_cells), :391 (batch_update_cells), and :737 (get_multiple_sheet_data). A tab named "Q3 Sales" needs the range 'Q3 Sales'!A1:C10; no code path in the server ever adds those quotes, so the Sheets API rejects the call on any tab whose title has a space, an apostrophe, or another reserved character. The README documents the sheet argument only as "the name of the sheet," with no note about quoting.
Two more gaps sit outside the README's own description. The ENABLED_TOOLS / --include-tools filter (server.py:190-218) applies mcp.tool() only when a tool's name matches the allow-list; anything else is returned undecorated, as a plain function that is never registered as an MCP tool — with no validation pass checking the allow-list names against the real tool set. A misspelled entry in --include-tools fails silently rather than erroring. And share_spreadsheet defaults its send_notification parameter to True while carrying a destructiveHint=True annotation (server.py:1034-1037, with the annotation at server.py:1028-1033) — the README never states that default, so an agent that calls share_spreadsheet without explicitly passing send_notification=False will notify whoever it shares with, by default, not silently.
05 Quirks, gaps and the honest verdict
- Unquoted sheet names break on real-world tab titles — any tab with a space, apostrophe, or reserved character fails every tool that builds a range against it, per
server.py:251, 305, 346, 391, 737. - Silent tool-filter typos — an
--include-toolsentry that doesn't match a real tool name is dropped with no error, perserver.py:190-218. - share_spreadsheet notifies by default —
send_notificationdefaults toTrue; an agent has to passFalseexplicitly to share quietly, and the README doesn't say so. - Different OAuth model than Google's own server — xing5's server runs on a single service-account key covering both Sheets and Drive, where Google ships a first-party, OAuth-client-scoped server per Workspace product.
- Development pace — the default branch's last commit and the latest GitHub release (v0.6.3), per the GitHub API, both land on 2026-05-14, and the GitHub API reported 23 open issues on 2026-07-27.
The honest trade is that xing5/mcp-google-sheets wins on being self-hostable with nothing more than a service-account key — no OAuth client to stand up per Workspace product — while conceding a defect that a README skim would never surface: unquoted sheet names break the server's own range-building on ordinary, human-named tabs. Use xing5/mcp-google-sheets for self-hosted, service-account-authenticated Sheets and Drive automation. Unless your spreadsheets carry tab names with spaces or apostrophes and you can't rename them — then either rename the tabs or wait on a fix to the range-building code before pointing an agent at them.
07 Frequently asked questions
- Is mcp-google-sheets an official Google product?
- No. It's a community server maintained by xing5, MIT-licensed, distinct from Google's own first-party Sheets MCP server in the Workspace MCP family (endpoint https://sheetsmcp.googleapis.com/mcp/v1).
- Why would a tool call fail against a sheet with a normal name like "Q3 Sales"?
- Every range-building call site builds the A1 range as an unquoted f-string (server.py:251, 305, 346, 391, 737); a tab name with a space needs quoting as 'Q3 Sales'!A1:C10, and nothing in the server ever adds those quotes.
- Does share_spreadsheet notify people by default?
- Yes — send_notification defaults to True (server.py:1034-1037), so calling share_spreadsheet without explicitly passing send_notification=False will notify whoever it's shared with.
- What transport and install command does it use?
- stdio transport, installed with uvx mcp-google-sheets@latest, authenticated via a Google service account (client_email) or user OAuth with Drive + Sheets scopes.