Repository navigation
Releases
v4.2.1
Changed
--dump-schemascarries the server's instructions, and lists fixed resources and prompts once the server has any.- For contributors: a pull request that changes the tool surface needs a commit footer naming each changed item;
CONTRIBUTING.mdgives the syntax. - For contributors: the schema diff compares each tool and resource whole, annotations included, so a removed resource fails as a removed tool does.
- For contributors:
make checkruns a docs gate. Decisions carry IDs indocs/architecture.md, and every citation must resolve. - For contributors: what was verified about Google lives in the comment at the code that depends on it, naming the live step that checks it.
- For contributors:
google.golang.org/apicannot be imported; depguard fails the lint on it. - For contributors: the spikes carry names.
-onlytakes names, comma-separated, and-listprints them.
Fixed
manage_sheet's description and its refusal to shrink a sheet namedelete_dimensions, the tool that removes rows and columns, notedit_dimensions.
Built by GoReleaser from the tag. Every archive carries the binary,
LICENSE and README, and ships an SBOM beside it.
Verify a download before you run it:
sha256sum -c checksums.txt --ignore-missing
cosign verify-blob checksums.txt --bundle checksums.txt.bundle \
--certificate-identity-regexp 'https://github\.com/mmedum/google-sheets-mcp/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
gh attestation verify google-sheets-mcp_*.tar.gz --repo mmedum/google-sheets-mcp.mcpb is the Claude Desktop bundle: open it and Claude Desktop
installs the server and asks for your OAuth client JSON, with no
config file to edit. It covers macOS, Windows and Linux on both
architectures. It does not log you in — install the binary as
well, run google-sheets-mcp login -secret <your client JSON> once,
and the bundle picks up the same credentials. Its SHA-256 is in the
same signed checksums.txt.
v4.2.0
Changed
make leaks-historypasses on the existing history. It allowssupport@github.com, the address on Dependabot's sign-off, by the whole address only.- The five writes that change what is there without being behind the destructive flag now say
destructiveHint: true, as the MCP spec readsfalseas "only additive updates":manage_sheet,edit_dimensions,manage_anchor,manage_cell_commentandmanage_data_source. claude.ai, ChatGPT and Codex may now ask before these; if you run them unattended there, allow them again. They still need noGSHEETS_ENABLE_DESTRUCTIVEand noconfirm.
Fixed
- A cell's 50,000-character limit is counted the way Google counts it, with an emoji counting as two and é as one. A cell of more than 50,000 bytes but no more than 50,000 such characters used to be refused before it was sent.
- An anchor's name is counted in characters, as its refusal says, so a name of 100 letters outside ASCII is taken.
- Google writes a time it does not have as 1970-01-01. A spreadsheet's modified time and a comment's times are now left out in that case rather than shown as 1970.
- The README and the setup guide said every app must list its scopes on the consent screen. Google asks for that list only from External apps, so an Internal app can skip the step.
loginanddoctorname a box left unticked at login as the other cause of a missing scope.
Built by GoReleaser from the tag. Every archive carries the binary,
LICENSE and README, and ships an SBOM beside it.
Verify a download before you run it:
sha256sum -c checksums.txt --ignore-missing
cosign verify-blob checksums.txt --bundle checksums.txt.bundle \
--certificate-identity-regexp 'https://github\.com/mmedum/google-sheets-mcp/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
gh attestation verify google-sheets-mcp_*.tar.gz --repo mmedum/google-sheets-mcp.mcpb is the Claude Desktop bundle: open it and Claude Desktop
installs the server and asks for your OAuth client JSON, with no
config file to edit. It covers macOS, Windows and Linux on both
architectures. It does not log you in — install the binary as
well, run google-sheets-mcp login -secret <your client JSON> once,
and the bundle picks up the same credentials. Its SHA-256 is in the
same signed checksums.txt.
v4.1.1
Changed
- The Claude Desktop bundle's OAuth client field may be left empty to use the client
google-sheets-mcp loginrecorded for the profile; a file picked there must be that same client, since the refresh token belongs to it. 4.1.0 required the field. - The Claude Desktop bundle's profile field says what a profile name may be: up to 64 characters from a to z, 0 to 9, - and _, starting with a letter or digit, with capitals read as lowercase. The server's refusal of another name states the same rule.
Fixed
- A profile name with a character that Unicode lowercases into a to z, such as the Kelvin sign (U+212A), is refused rather than read as another profile's name.
- A variable set to spaces alone is unset, as an empty one is,
GSHEETS_CONFIG_DIRandGSHEETS_REFRESH_TOKENincluded, and the spaces around any value are dropped; a bundle field cleared to a space no longer stops the server.
Built by GoReleaser from the tag. Every archive carries the binary,
LICENSE and README, and ships an SBOM beside it.
Verify a download before you run it:
sha256sum -c checksums.txt --ignore-missing
cosign verify-blob checksums.txt --bundle checksums.txt.bundle \
--certificate-identity-regexp 'https://github\.com/mmedum/google-sheets-mcp/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
gh attestation verify google-sheets-mcp_*.tar.gz --repo mmedum/google-sheets-mcp.mcpb is the Claude Desktop bundle: open it and Claude Desktop
installs the server and asks for your OAuth client JSON, with no
config file to edit. It covers macOS, Windows and Linux on both
architectures. It does not log you in — install the binary as
well, run google-sheets-mcp login -secret <your client JSON> once,
and the bundle picks up the same credentials. Its SHA-256 is in the
same signed checksums.txt.
v4.1.0
Added
- The Claude Desktop bundle asks for the profile, read-only,
enable_destructive,enable_data_sourcesandallow_external_formulasas well as the OAuth client file, each off or empty unless you set it, names Google's privacy policy, and needs Claude Desktop 0.10.0 or later.
Changed
- The bundle stages its binaries as
server/google-sheets-mcp-darwin,server/google-sheets-mcp.exe,server/google-sheets-mcp-linux-amd64andserver/google-sheets-mcp-linux-arm64, and its Linux launcher asserver/launch-linux.sh.
Built by GoReleaser from the tag. Every archive carries the binary,
LICENSE and README, and ships an SBOM beside it.
Verify a download before you run it:
sha256sum -c checksums.txt --ignore-missing
cosign verify-blob checksums.txt --bundle checksums.txt.bundle \
--certificate-identity-regexp 'https://github\.com/mmedum/google-sheets-mcp/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
gh attestation verify google-sheets-mcp_*.tar.gz --repo mmedum/google-sheets-mcp.mcpb is the Claude Desktop bundle: open it and Claude Desktop
installs the server and asks for your OAuth client JSON, with no
config file to edit. It covers macOS, Windows and Linux on both
architectures. It does not log you in — install the binary as
well, run google-sheets-mcp login -secret <your client JSON> once,
and the bundle picks up the same credentials. Its SHA-256 is in the
same signed checksums.txt.
v4.0.0
Added
connect_data_sourceconnects a BigQuery query or table through Connected Sheets, asmanage_data_sourceadddid, withGSHEETS_ENABLE_DATA_SOURCES=true. Your client's approval ofmanage_data_sourceno longer covers starting a new billed query.GSHEETS_ALLOW_EXTERNAL_FORMULASlets a write createIMPORTXML,IMPORTDATA,IMPORTHTML,IMPORTFEED,IMAGE,HYPERLINKorIMPORTRANGE. It is off by default.transform_rangetakesexpect_checkpoint, and a dry run of it or ofwrite_valuesreturns thecheckpointan overwrite needs.
Changed
- Breaking: the server no longer asks you before a write; your MCP client approves each call. claude.ai and Codex prompt for the tools marked destructive, VS Code for every tool that writes, and in Claude Code an
askrule per tool does it, as the README shows. Registration,confirm: true, the guards anddry_runare unchanged. A client that runs with nobody watching can now make every write its settings register, so leaveGSHEETS_ENABLE_DESTRUCTIVEandGSHEETS_ENABLE_DATA_SOURCESoff for one. - Breaking: if you followed 3.1.0 and put
delete_sheet,delete_dimensions,clear_values,delete_data_sourceanddelete_cell_commenton Claude Code's allow list, move them topermissions.ask. With the server's question gone, an allowed delete runs with nobody asked. - Breaking: only
delete_data_sourcecarries Claude Code'srequiresUserInteractionmark, since it takes a sheet and Google unlinks what was built on the source. Claude Code asks on every such call whatever your rules say, and refuses it in a run that cannot ask (-p, dontAsk). The other four deletes no longer carry it. write_values,transform_range,format_cells,manage_range,manage_chartandmanage_pivot_tablesaydestructiveHint: true, since an argument can take away what they land on, so Codex and claude.ai prompt for them.- Breaking:
overwriteandoverwrite_formulasonwrite_valuesandtransform_rangeneedexpect_checkpoint, the checkpoint of the cells they replace. Without it the call is refused[invalid]with that checkpoint, which the guard's refusal and a dry run also give. A change to those cells after that read is[conflict]. - Breaking:
manage_data_sourceno longer connects a data source; useconnect_data_source.refreshneedsid: refreshing every source by leavingidout is refused, listing the ids.cancel_refreshstill takes every source without one. - Breaking:
delete_data_sourceneedssheet, the title of the sheet the source made, so the call your client shows names the tab that goes. A title that is not that source's sheet now is[conflict]. A call withoutid, or with one the spreadsheet does not have, is refused naming each source and its sheet. - Breaking:
delete_dimensionsrefuses ananchor:band, andclear_valuesananchor:range or no range at all, each naming the band or range it stands for now, so the call your client shows says what goes. A whole sheet named in A1 still clears. - Breaking:
write_valuesandappend_rowsno longer takeallow_external_formulas. A formula that reaches outside the spreadsheet is written only when the server is started withGSHEETS_ALLOW_EXTERNAL_FORMULAS=true, by these, bycreate_spreadsheet's seed values and by atransform_rangefind_replacereplacement. - Breaking:
append_rowsno longer takesinsertoroverwrite, and always inserts. Usewrite_valuesto write over rows you know. - Breaking: a
transform_rangefind_replaceinside formulas is run over each formula first, and refused where one would come out reaching outside the spreadsheet, such asX(replaced by(turning=IMAGEX(…)into=IMAGE(…), unlessGSHEETS_ALLOW_EXTERNAL_FORMULASis set. A regular expression with a lookbehind or a backreference cannot be run first, so over formulas it is refused the same way. - Breaking: a
transform_rangecopy_pasteof everything or of formulas, and anauto_fill, refuse to copy a formula that reaches outside the spreadsheet unlessGSHEETS_ALLOW_EXTERNAL_FORMULASis set, since each copy fetches with the cells beside it. - The server's instructions say that
overwritecarries a decision you made, not a way past a refusal. - Breaking: the Go module path is now
github.com/mmedum/google-sheets-mcp/v4, as Go requires for a new major version; install withgo install github.com/mmedum/google-sheets-mcp/v4/cmd/google-sheets-mcp@latest.
Removed
- Breaking:
GSHEETS_REQUIRE_PROMPTand-require-prompt. Set to anything but false, the server refuses to start rather than ignore it; unset it.
Fixed
manage_data_sourcerefusesaction: delete, namingdelete_data_source; it used to preview the delete, and refuse it asking for aconfirmit does not take.- A
connect_data_sourcedry run and result name the whole table, with the project it lives in, not only the project charged.
Security
- Built with Go 1.27.3, which fixes GO-2026-6809 in
crypto/x509, whichgovulncheckfound reachable from this server: intermediate certificates known to be compromised are no longer trusted.
Built by GoReleaser from the tag. Every archive carries the binary,
LICENSE and README, and ships an SBOM beside it.
Verify a download before you run it:
sha256sum -c checksums.txt --ignore-missing
cosign verify-blob checksums.txt --bundle checksums.txt.bundle \
--certificate-identity-regexp 'https://github\.com/mmedum/google-sheets-mcp/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
gh attestation verify google-sheets-mcp_*.tar.gz --repo mmedum/google-sheets-mcp.mcpb is the Claude Desktop bundle: open it and Claude Desktop
installs the server and asks for your OAuth client JSON, with no
config file to edit. It covers macOS, Windows and Linux on both
architectures. It does not log you in — install the binary as
well, run google-sheets-mcp login -secret <your client JSON> once,
and the bundle picks up the same credentials. Its SHA-256 is in the
same signed checksums.txt.
v3.1.2
Changed
manage_rangetableaddwithcolumn_typessays why when Google answers with an internal error (HTTP 500) and nothing was added: Google has refused table adds with column types after about four in one spreadsheet, and an add withoutcolumn_typeswas still taken. Whether the columns can be typed after that is not known, and the result says so. It used to say only that Google had been seen to fail every later table add, for a reason not known.manage_rangedata_validationaddandupdateare refused before anything is sent over the cells of a table's dropdown column, naming the cells, and a dry run says so. Google refuses a rule there: "This operation is not allowed on cells in typed columns." The refusal says to change the column's list withtableupdateandcolumn_types.
Built by GoReleaser from the tag. Every archive carries the binary,
LICENSE and README, and ships an SBOM beside it.
Verify a download before you run it:
sha256sum -c checksums.txt --ignore-missing
cosign verify-blob checksums.txt --bundle checksums.txt.bundle \
--certificate-identity-regexp 'https://github\.com/mmedum/google-sheets-mcp/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
gh attestation verify google-sheets-mcp_*.tar.gz --repo mmedum/google-sheets-mcp.mcpb is the Claude Desktop bundle: open it and Claude Desktop
installs the server and asks for your OAuth client JSON, with no
config file to edit. It covers macOS, Windows and Linux on both
architectures. It does not log you in — install the binary as
well, run google-sheets-mcp login -secret <your client JSON> once,
and the bundle picks up the same credentials. Its SHA-256 is in the
same signed checksums.txt.
v3.1.1
Fixed
- The Go module and the release binaries are one commit again. The module for 3.1.0 was fetched from an earlier commit than the one its binaries were built from; the two differ only in a line of documentation. The code is the same as 3.1.0, so nothing needs doing beyond installing this version.
Built by GoReleaser from the tag. Every archive carries the binary,
LICENSE and README, and ships an SBOM beside it.
Verify a download before you run it:
sha256sum -c checksums.txt --ignore-missing
cosign verify-blob checksums.txt --bundle checksums.txt.bundle \
--certificate-identity-regexp 'https://github\.com/mmedum/google-sheets-mcp/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
gh attestation verify google-sheets-mcp_*.tar.gz --repo mmedum/google-sheets-mcp.mcpb is the Claude Desktop bundle: open it and Claude Desktop
installs the server and asks for your OAuth client JSON, with no
config file to edit. It covers macOS, Windows and Linux on both
architectures. It does not log you in — install the binary as
well, run google-sheets-mcp login -secret <your client JSON> once,
and the bundle picks up the same credentials. Its SHA-256 is in the
same signed checksums.txt.
v3.1.0
Added
edit_dimensionshides and unhides rows and columns, andread_rangenames the hidden rows and columns inside the range it read.read_cell_commentslists the comment threads on a spreadsheet's cells, each on the cell it is on now, with its status, assignee and posts.manage_cell_commentadds a comment to a cell, replies, edits a post, resolves and reopens. Google emails an assignee, without checking the address, and may notify an address the text names.manage_rangeconditional_formattakesgradient, a color scale of two or three points such as["min #ffffff", "percentile 50 #ffd666", "max #57bb8a"].read_formattingreads a color scale back in the same spelling, where it used to say only "color gradient". A number is written the way the spreadsheet's locale writes it: underde_DE,1,5, since Google refuses1.5.manage_rangetabletakescolumn_typeson add and update, such as["B date", "Amount currency", "Status dropdown: Open, In progress, Done"], naming each column by letter or by its header. Each column keeps its header's text as its name; Google writes a name of its own, such as "Column 1", into an empty header cell, and the result says so. An update changes only the columns named and keeps every other column's type and dropdown list, and every header's text. Google writes a column's name into its header cell as plain text, so an add is refused while the header of a column it types holds a smart chip or rich text, such as a bold word, and an update while any header cell holds one of those or a formula. A boolean column shows checkboxes and fills its empty cells with FALSE; it is refused while a cell under its header holds anything but a TRUE or FALSE value, since Google turns a word, and even text reading TRUE, into FALSE. A dropdown column is refused while a cell under its header has a data validation rule of its own, naming the cells: Google replaces that rule with the table's list and says nothing.get_spreadsheetshows a table's column types in a spellingcolumn_typestakes back, a dropdown with its options in parentheses, where it used to show Google's names for them, such asDOUBLE.manage_pivot_tablegroups by a rule, filters, and works out calculated values. A group such as"Date by year_month"buckets dates by a part of them, and"Age every 10 from 20 to 70"buckets numbers.filterskeeps the rows to summarize, such as"Region show East, West","Amount number_greater 100"or"Day date_after past_week", and replaces every filter the pivot table had;clear_filtersremoves them. A value starting with=is a calculated value and needs a name:"=SUM(Revenue)/SUM(Cost) as Margin"uses the formula as written, and"=Revenue-Cost sum as Margin"works it out per row and sums it.listreports each pivot table'srows,columns,valuesandfiltersin the same spelling, so they can be changed and sent back. A grouping made by hand in Sheets reads as"Region by hand", and an update that leaves the groups out keeps it.stdevpandvarpjoin the summaries.delete_cell_commentdeletes a comment thread or one reply. Like the other deletes it is registered only withGSHEETS_ENABLE_DESTRUCTIVE=true, needsconfirm, and asks the person first. A thread or reply that is not there, such as one a repeat call already deleted, is reported gone and nothing is sent; Google answers an id it never had the same way, so a mistyped id reads as gone too.
Changed
manage_rangetableaddis refused before anything is sent while a cell of the header row holds a formula, naming the cells, and a dry run says so. Google takes no table over one: "Formulas are not supported in a table header row."- A delete asks once in Claude Code, not twice. In a client that can ask the person,
delete_sheet,delete_dimensions,clear_valuesanddelete_data_sourceno longer carry therequiresUserInteractionmark; the server's own question, which shows what the write destroys, is the confirmation. To see only that question, add these four and the newdelete_cell_commentto Claude Code's allow list. A Claude CodeElicitationhook that accepts now confirms these deletes by itself,claude -pincluded, where the mark used to refuse the call before it reached the server.
Fixed
manage_rangetableaddsays whether the table was added when Google answers with an internal error (HTTP 500) or no answer comes. It reads the spreadsheet's tables afterwards and reports the table added, or nothing added and the call safe to repeat; it used to say only that the add may have been applied. Google has been seen to fail every table add in a spreadsheet after several were taken, for a reason not known.write_valuesrefuses a formula into a table's header row, naming the cells. Google answered such a write with success and replaced the formula with a column name of its own, such as "Column 2".manage_pivot_tableupdatewith a newsourcerefuses one that would change what a kept group, value or filter reads, and names each. Each keeps its position counted from the source's first column. A source too narrow left a pivot that showed nothing for it, and Google accepted that. A source that starts in another column moved every kept one onto other data, with nothing said. Pass the groups, values and filters again to change the source anyway. A kept calculated value names its columns by heading, so it does not stop a new source.- The schema diff compares every input and output field at any depth against
testdata/schema-baseline.json, the newest release's surface, and fails when that file is not the newest release's. It compared top-level fields against the last tag, so a lost nested output field passed. It fails on a field removed, an output that may return another type or be missing where it was required, and an input that takes fewer types or no longer takes a value it listed. An input that becomes nullable, or takes a number for an integer, passes.make schema-baseline VERSION=vX.Y.Zrecords the surface in a release commit. - A write over a smart chip (a person or a file link) says so before it erases it, and so do
transform_rangecopy_paste,cut_paste,auto_fillandtext_to_columnswhere they land. A chip reads as its text, and the refusal called the cell only "not empty";overwriteerased the chip with nothing said.
Security
- Built with Go 1.27.2, which fixes nine advisories in
net/http, its HTTP/2 code,crypto/tlsandnet/textprotothatgovulncheckfound reachable from this server.
Built by GoReleaser from the tag. Every archive carries the binary,
LICENSE and README, and ships an SBOM beside it.
Verify a download before you run it:
sha256sum -c checksums.txt --ignore-missing
cosign verify-blob checksums.txt --bundle checksums.txt.bundle \
--certificate-identity-regexp 'https://github\.com/mmedum/google-sheets-mcp/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
gh attestation verify google-sheets-mcp_*.tar.gz --repo mmedum/google-sheets-mcp.mcpb is the Claude Desktop bundle: open it and Claude Desktop
installs the server and asks for your OAuth client JSON, with no
config file to edit. It covers macOS, Windows and Linux on both
architectures. It does not log you in — install the binary as
well, run google-sheets-mcp login -secret <your client JSON> once,
and the bundle picks up the same credentials. Its SHA-256 is in the
same signed checksums.txt.
v3.0.2
Fixed
- 3.0.1 was tagged but never published: its release stopped on a status line that still named 3.0.0. 3.0.2 carries the same fixes.
Built by GoReleaser from the tag. Every archive carries the binary,
LICENSE and README, and ships an SBOM beside it.
Verify a download before you run it:
sha256sum -c checksums.txt --ignore-missing
cosign verify-blob checksums.txt --bundle checksums.txt.bundle \
--certificate-identity-regexp 'https://github\.com/mmedum/google-sheets-mcp/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
gh attestation verify google-sheets-mcp_*.tar.gz --repo mmedum/google-sheets-mcp.mcpb is the Claude Desktop bundle: open it and Claude Desktop
installs the server and asks for your OAuth client JSON, with no
config file to edit. It covers macOS, Windows and Linux on both
architectures. It does not log you in — install the binary as
well, run google-sheets-mcp login -secret <your client JSON> once,
and the bundle picks up the same credentials. Its SHA-256 is in the
same signed checksums.txt.
v3.0.0
Added
- The server asks the person through the client before
delete_sheet,delete_dimensions,clear_values,delete_data_source,manage_data_sourceadd, and a refresh of every data source. Only an accept lets the write go ahead. GSHEETS_REQUIRE_PROMPT=truerefuses those writes when the client cannot ask.
Changed
- Breaking: a client that declares elicitation and does not accept, including one answering with nobody present, gets
[blocked]on those writes. - Breaking: the module path is
github.com/mmedum/google-sheets-mcp/v3; install withgo install github.com/mmedum/google-sheets-mcp/v3/cmd/google-sheets-mcp@latest.
Fixed
delete_data_sourcewithdry_runno longer needsconfirm.delete_data_sourcefor an id the spreadsheet does not have is[not_found].- The schema dump and the architecture record the SDK as v1.8.0, and the configuration reference names all four destructive tools.
Built by GoReleaser from the tag. Every archive carries the binary,
LICENSE and README, and ships an SBOM beside it.
Verify a download before you run it:
sha256sum -c checksums.txt --ignore-missing
cosign verify-blob checksums.txt --bundle checksums.txt.bundle \
--certificate-identity-regexp 'https://github\.com/mmedum/google-sheets-mcp/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
gh attestation verify google-sheets-mcp_*.tar.gz --repo mmedum/google-sheets-mcp.mcpb is the Claude Desktop bundle: open it and Claude Desktop
installs the server and asks for your OAuth client JSON, with no
config file to edit. It covers macOS, Windows and Linux on both
architectures. It does not log you in — install the binary as
well, run google-sheets-mcp login -secret <your client JSON> once,
and the bundle picks up the same credentials. Its SHA-256 is in the
same signed checksums.txt.