Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
ASKADS_TELEMETRYNoSet to 0 to opt out of telemetry.
GOOGLE_SHEETS_API_BASENoGoogle Sheets API base URL override.
GOOGLE_SHEETS_CLIENT_IDNoOAuth client ID.
GOOGLE_SHEETS_TIMEOUT_MSNoPer-request timeout; default 60000 ms.60000
GOOGLE_SHEETS_MAX_RETRIESNoTemporary-error retries; default 3.3
GOOGLE_SHEETS_ACCESS_TOKENNoShort-lived (~1 h) alternative to the OAuth trio.
GOOGLE_SHEETS_CLIENT_SECRETNoOAuth client secret.
GOOGLE_SHEETS_REFRESH_TOKENNoOAuth refresh token.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
auth_statusA

Shows whether this server is connected to Google: token presence and source (env variables or a stored in-chat login), expiry, the Google account email, granted vs missing OAuth scopes, where the credentials file lives and where the OAuth client comes from. Makes no network calls and never returns the token itself. Call it first when other tools report the server is not connected.

setup_instructionsA

Step-by-step checklist for connecting this server to Google: creating a Google Cloud project and a Desktop-app OAuth client, publishing the consent screen (mandatory — Testing-mode refresh tokens die after 7 days), downloading the client JSON and handing its PATH to set_client. Works without any credentials; the checklist shortens to 'enable the API + log in' when an OAuth client is already configured (one client serves the whole mcp-google-* line). Never asks the user to paste secrets into the chat.

set_clientA

Saves the OAuth client credentials from the JSON file downloaded from Google Cloud Console ('Download JSON' on a Desktop-app client). Pass the file PATH — the secret must never be pasted into the chat. The client is stored once in the shared ~/.config/mcp-google-auth/client.json (owner-only) and reused by every mcp-google-* server; tokens stay per-server. After this, call start_login.

start_loginA

First step of connecting from the chat, without editing config files or restarting the client. Returns authorizeUrl — show it to the user as a clickable link and ask them to open it in the browser ON THIS MACHINE, pick the Google account and approve access. A one-shot listener on 127.0.0.1 catches Google's redirect; the code is exchanged locally and never passes through the chat. Does not open the browser itself. The attempt lives 10 minutes; when the browser shows the success page, call finish_login.

finish_loginA

Second step: confirms the browser consent finished, saves the tokens to an owner-only file and verifies the login with a read-only identity call, returning the account email and the granted scopes. After success every tool works immediately — no client restart. If the user granted only part of the requested permissions, the login is still saved and missingScopes lists what will not work. Logging in under a different Google account replaces the previous login (its refresh token is revoked best-effort) and the response carries previousAccountEmail so the change never goes unnoticed.

logoutA

Revokes the stored token at Google (oauth2.googleapis.com/revoke) and deletes the local credentials file. Tokens supplied via env variables are NOT touched — remove them from the MCP client config manually; envTokenStillSet in the response says whether any are still in effect.

create_spreadsheetA

Creates a new Google Sheets spreadsheet and returns it: spreadsheetId, spreadsheetUrl, properties (title, locale, timeZone) and sheets[] with each sheet's numeric sheetId. sheet_titles creates one tab per title in order (omitted = a single default "Sheet1"). The file lands in the authorized user's My Drive root — moving it into a folder needs the Drive API, which this server does not cover. Save the returned spreadsheetId: the Sheets API has no list endpoint of its own (search_spreadsheets exists, but it needs a Drive scope on the token).

get_spreadsheetA

Returns the spreadsheet's structure: properties (title, locale, timeZone), sheets[] with properties (sheetId, title, index, gridProperties incl. rowCount/columnCount and frozenRowCount/frozenColumnCount), plus each sheet's protectedRanges, conditionalFormats, tables and charts, and the spreadsheet's namedRanges. Call this FIRST whenever a structural tool needs a sheetId, protectedRangeId, tableId, chartId or a conditional-format rule index — titles are not addresses. By default no cell data is returned; include_grid_data=true (optionally limited to ranges) embeds cells but is heavy — prefer read_values for data. fields is a partial-response mask to trim the payload, e.g. "sheets.properties".

search_spreadsheetsA

Finds Google Sheets spreadsheets the authorized user can open (own files and shared drives; trashed files are excluded): id, name, createdTime, modifiedTime, owners and webViewLink per file, newest-modified first by default. name_contains filters by name substring; omit it to list everything. Paginate with page_token from nextPageToken. This is the one read that goes through the Drive API internally, so the OAuth token needs a Drive scope (drive, drive.readonly or drive.file for app-created files) — with only the spreadsheets scope it fails with 403 while every other tool still works.

read_valuesA

Reads one or more A1 ranges in a single call (one request against the quota, however many ranges) and returns valueRanges[] — each with its resolved range and a 2-D values array (outer = rows unless major_dimension=COLUMNS). Trailing empty rows/columns are omitted; a fully empty range has no values key at all. value_render_option: FORMATTED_VALUE (default, strings as displayed, honoring the cell's number format and locale), UNFORMATTED_VALUE (raw numbers/booleans), FORMULA (the formula text, e.g. "=SUM(A1:A10)" — the way to read formulas). With UNFORMATTED_VALUE, dates arrive as serial numbers unless date_time_render_option=FORMATTED_STRING.

write_valuesA

Overwrites one A1 range with a 2-D values matrix (rows first) and returns updatedRange/updatedRows/updatedColumns/updatedCells. The matrix is anchored at the range's top-left corner; cells beyond the matrix keep their old content, and a null entry skips (does not clear) that cell — use clear_values to empty cells. value_input_option USER_ENTERED (default) parses input like typing in the UI: "=SUM(A1:A10)" becomes a live formula, "1,234" and "2026-01-15" become number/date per the spreadsheet locale; RAW stores everything as literal values. For several ranges use batch_write_values (one quota unit instead of N).

batch_write_valuesA

Overwrites several A1 ranges in ONE call — one write against the per-minute quota instead of one per range, so always prefer this over looping write_values. data is a list of {range, values} pairs; all are written with the same value_input_option (USER_ENTERED parses formulas/numbers/dates, RAW stores literally). Returns totalUpdatedCells and a per-range responses[] breakdown. Like write_values, null entries skip cells rather than clearing them.

append_valuesA

Appends rows after the last row of the data table that contains the given range — pass the table's region (e.g. "Sheet1!A1:D1" or just "Sheet1") and the API finds the first free row itself; the response's updates.updatedRange shows where the rows actually landed. insert_data_option INSERT_ROWS pushes existing data below down; OVERWRITE (default behaviour) writes into the free rows after the table. Never retried after an ambiguous failure — re-appending would duplicate the rows, so check the sheet first (read_values) before re-sending.

clear_valuesA

Empties the VALUES of one or more A1 ranges in a single call — cell contents and formulas are gone (no undo through the API), while formatting, data validation, notes, conditional formats and merges all stay. To also remove formatting use format_cells or raw_request; to delete whole rows/columns (not just their content) use manage_dimensions action=delete.

manage_sheetsA

Manages the sheets (tabs) of a spreadsheet. action=add creates a tab (title required; optional index position and row_count/column_count — default 1000×26). action=duplicate copies a tab within the same spreadsheet (sheet_id; optional title for the copy and index). action=rename changes a tab's title (sheet_id + title; the numeric sheetId never changes, so other tools keep working). action=delete removes the tab AND all its data — irreversible through the API, and deleting the last remaining sheet fails. action=copy_to copies a tab into ANOTHER spreadsheet (sheet_id + destination_spreadsheet_id; the copy arrives named "Copy of ..." — rename it there). Get sheet_id values from get_spreadsheet; every action except add returns batchUpdate replies with the affected sheet's properties.

format_cellsA

Applies cell formatting to a range: background_color, text color/bold/italic/strikethrough/underline/font_size/font_family, horizontal/vertical alignment, wrap_strategy, and number format (number_format_type NUMBER/PERCENT/CURRENCY/DATE/TIME/DATE_TIME/SCIENTIFIC/TEXT with an optional number_format_pattern like "#,##0.00" or "dd.mm.yyyy"). Only the provided properties are touched — the update mask is computed automatically, so existing formatting outside it survives; at least one formatting field is required. The range is a grid rectangle addressed by sheet_id + 0-based indexes (get sheet_id from get_spreadsheet). Colors are "#RRGGBB" hex strings.

set_frozenA

Freezes the first N rows and/or columns of a sheet so they stay visible while scrolling (typical: frozen_rows=1 pins the header). 0 unfreezes. At least one of frozen_rows / frozen_columns is required; the other stays as it is. You cannot freeze all rows or all columns of a sheet — at least one unfrozen row/column must remain.

set_bordersA

Draws borders around and/or inside a grid range. top/bottom/left/right are the range's outer edges; inner_horizontal/inner_vertical are the grid lines between cells inside it. Each side takes {style, color?} — styles SOLID, SOLID_MEDIUM, SOLID_THICK, DOTTED, DASHED, DOUBLE, or NONE to remove that side's border. Only the provided sides change; at least one is required. Colors are "#RRGGBB" hex (default black).

manage_dimensionsA

Row/column operations on a run of rows (dimension=ROWS) or columns (dimension=COLUMNS), addressed by sheet_id + 0-based start_index (inclusive) and end_index (exclusive) — e.g. columns A-C = start 0, end 3. action=resize sets an exact pixel_size; auto_resize fits to content; insert adds empty rows/columns at start_index (inherit_from_before=true copies formatting from the row/column before instead of after); delete removes them WITH their data (irreversible; cell references below/right shift); hide/show toggle visibility without touching data; group/ungroup add or remove a collapsible outline group over the run (groups nest — repeat group on a subrange for a deeper level).

set_data_validationA

Sets — or clears — a data-validation rule on a grid range. With condition_type set, every cell in the range gets the rule: ONE_OF_LIST with condition_values plus show_custom_ui=true is the classic in-cell dropdown; ONE_OF_RANGE takes a "=Sheet1!A1:A10" formula; NUMBER_/TEXT_/DATE_ conditions restrict input; CUSTOM_FORMULA takes a formula evaluated per cell. strict=true rejects invalid input outright, strict=false only shows a warning; input_message is the help text shown on the cell. OMIT condition_type (and the other rule fields) to REMOVE validation from the range. Overwrites any previous rule on the range — one rule per cell.

manage_protected_rangesA

Manages protections that stop other editors from changing cells. action=add protects a grid range (or a named range via named_range_id; a range with only sheet_id protects the whole sheet): warning_only=true merely warns before edits, otherwise only the listed editor_users/editor_groups (emails) plus the owner may edit — note the calling user is NOT added automatically. Returns the new protectedRangeId in the replies. action=update changes description/warning_only/editors of an existing protection (protected_range_id required; provided fields replace the old values). action=delete removes the protection — the cells and data stay, but anyone with edit access can change them again. Find existing protectedRangeIds via get_spreadsheet.

manage_conditional_formatsA

Manages conditional-format rules that style cells when a condition holds (boolean rules; gradient color scales need raw_request). Rules are addressed by SHEET + INDEX in that sheet's rule list — get current rules and indexes from get_spreadsheet (sheets[].conditionalFormats), and re-read after every mutation because add/delete shift later indexes. action=add inserts a rule at index (default 0 = highest priority; rules are evaluated in order and the first match wins): needs ranges, condition_type (+condition_values; CUSTOM_FORMULA with a "=..." formula is the most flexible) and at least one format field (background_color, text_color, bold, italic). action=update replaces the ENTIRE rule at sheet_id+index with the newly provided one. action=delete removes the rule at sheet_id+index.

manage_tablesA

Manages structured tables (the "Convert to table" feature: named ranges with per-column types, filters and formatting). action=add creates a table over a grid range whose FIRST ROW becomes the header: name (must be unique in the spreadsheet) + range required; column_properties optionally types the columns — a list of raw TableColumnProperties objects, e.g. [{"columnIndex":0,"columnName":"Task","columnType":"TEXT"},{"columnIndex":1,"columnName":"Done","columnType":"BOOLEAN"}] (columnType TEXT/PERCENT/DROPDOWN/DOUBLE/CURRENCY/DATE/TIME/DATE_TIME/BOOLEAN; DROPDOWN adds dataValidationRule). The reply carries the new table with its tableId. action=update renames and/or re-ranges an existing table (table_id + name and/or range; expanding the range grows the table). action=delete removes the TABLE DEFINITION only — the cell data stays; clear the cells separately if needed. Find tableIds via get_spreadsheet (sheets[].tables).

manage_chartsA

Manages embedded charts. action=add builds a chart from chart_type (COLUMN/BAR/LINE/AREA/STEPPED_AREA/SCATTER/PIE), domain_range (x-axis labels / pie labels), series_ranges (one grid range per data series; PIE takes exactly one) and optional title/legend_position/header_count (rows of the ranges treated as headers, default 1) — place it with anchor {sheet_id,row_index,column_index} (the cell under the chart's top-left corner) or new_sheet=true for its own chart sheet; the reply carries the new chartId. Ranges should be single columns (or rows) including the header cell. For chart kinds beyond the basic set (combo, waterfall, histogram, org …) pass a raw Sheets API ChartSpec via spec instead — it overrides the simplified fields. action=update REPLACES the whole spec of an existing chart (chart_id + the same spec-building fields; there is no partial chart update). action=delete removes the chart by chart_id. Find chartIds via get_spreadsheet (sheets[].charts).

manage_permissionsA

Shares the spreadsheet (Drive permissions on the file — the OAuth token needs a Drive scope; the spreadsheets scope alone gets 403 here while every Sheets tool still works). action=list shows who has access: id, type, role, emailAddress/domain per permission; one page per call (shared-drive files cap a page at 100) — when the reply carries nextPageToken, pass it back as page_token for the rest. action=grant gives role reader/commenter/writer to type user/group (email_address required), domain (domain required, e.g. "example.com") or anyone (makes the link public — use deliberately); send_notification_email (default true for users) and email_message control the notification, allow_file_discovery lets domain/anyone grants surface in search. action=update changes an existing permission's role (permission_id + role). action=revoke removes a permission (permission_id) — the person loses access immediately. Ownership transfer is not supported by this server. Protecting individual ranges from co-editors is manage_protected_ranges, not this tool.

raw_requestA

Escape hatch to call any Google Sheets API v4 path directly, for requests the typed tools don't cover — e.g. a batchUpdate with mergeCells, named ranges, banding, basic filters, slicers, sortRange, findReplace, gradient conditional-format rules, developer metadata, or several requests in one atomic call: path "v4/spreadsheets/:batchUpdate", method POST, body {"requests":[...]}. The path may carry a query string. The Bearer token is added automatically; the method defaults to GET (values updates use PUT). Sheets API paths only — Drive paths are not reachable here.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A4.4/5.0

Scored across 26 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: read/write/append/clear values, manage sheets/dimensions/protected ranges/conditional formats/tables/charts/permissions, and auth tools are separated by function. Overlaps are minimized by using action parameters within a tool rather than separate tools (e.g., manage_sheets covers add/duplicate/rename/delete/copy_to), which keeps boundaries clean.

Naming Consistency5/5

Tool names follow a highly consistent snake_case verb_noun pattern: read_values, write_values, append_values, clear_values, create_spreadsheet, get_spreadsheet, manage_sheets, format_cells, set_data_validation, etc. The few auth tools (logout, auth_status, finish_login, start_login) also fit the pattern with clear verbs/nouns.

Tool Count3/5

26 tools is at the high end for a Google Sheets MCP server and borders on heavy; while many are essential, some could potentially be consolidated (e.g., format_cells, set_borders, set_frozen could be batch_update-style actions). Still, the count is plausible given the breadth of the Sheets API surface.

Completeness4/5

The toolset covers most core Google Sheets operations (CRUD on spreadsheets, values, sheets, formatting, validation, dimensions, protections, conditional formats, tables, charts, permissions) and includes raw_request as an escape hatch. Minor gaps exist: no direct search for spreadsheets without Drive scope, no batch update for values other than write, and some advanced features (named ranges, banding, filters) require raw_request.

Maintenance

ActivityMaintained
ResponsivenessNo issues